2014-02-21 4 views
0

UIDeviceOrientationDidChangeNotification вызывается несколько раз, когда устройство меняет ориентацию. Я не уверен, почему это происходит или как это исправить.UIDeviceOrientationDidChangeNotification вызов несколько раз

То, что я пытаюсь сделать, состоит в том, чтобы сохранить контент на экране прокрутки одинаковым, поэтому, когда пользователь поворачивает экран, приложение сохраняет страницу, на которой они были.

Нечетная вещь, когда я поворачиваю экран при первом выполнении кода, как хотелось бы. Но каждый раз после этого код выполняется несколько раз и, в конце концов, набор содержимого устанавливается 0. 0.

Вот что у меня есть.

- (void)loadView { 

    //some code that sizes itself depending on the current orientation 
    //WILL BE CALLED AFTER EVERY ORIENTATION CHANGE 

} 

- (void)viewDidLoad { 

    //begin generating messages 
    [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; 


    [[NSNotificationCenter defaultCenter] 
     addObserver:self selector:@selector(orientationChanged:) 
     name:UIDeviceOrientationDidChangeNotification 
     object:[UIDevice currentDevice]]; 

    //if is portrait and was landscape 
    if (orientation==1 && temp==2) { 
     int cal = offsetHolder.x/screenframe.size.height; 
     offsetHolder.x = cal * screenframe.size.width; 
     ScrollView.contentOffset = offsetHolder; 
    } 

    //if is landscape and was portrait 
    if (orientation==2 && temp==1) { 
     int cal = offsetHolder.x/screenframe.size.width; 
     offsetHolder.x = cal * screenframe.size.height; 
     ScrollView.contentOffset = offsetHolder; 
    } 


} 

При изменении ориентации меняю значение «int orientation», затем вызывается loadview, чтобы изменить размер представления. Тогда я называю viewdidload, чтобы получить надлежащее contentoffset

- (void) orientationChanged:(NSNotification *)note { 

    CGRect screenframe = [[UIScreen mainScreen] bounds]; 

    //holding the current offset 
    offsetHolder = ScrollView.contentOffset; 

    if ([[UIDevice currentDevice] orientation] == 1 || [[UIDevice currentDevice] orientation] == 0 || [[UIDevice currentDevice] orientation] == UIDeviceOrientationPortraitUpsideDown) { 
     temp=orientation; 
     orientation = 1; 

     [self loadView]; 
     [self viewDidLoad]; 
    } 

    else if ([[UIDevice currentDevice] orientation] == UIDeviceOrientationFaceDown ||  [[UIDevice currentDevice] orientation] == UIDeviceOrientationFaceUp){ 

     temp=orientation; 
    } 

    else{ 
     temp=orientation; 
     orientation = 2; 
     [self loadView]; 
     [self viewDidLoad]; 
    } 
} 

EDIT:

Я нашел эту проблему. То, что я делаю, это создать еще один экземпляр self.view вместо того, чтобы перезаписать это. Есть ли простой способ уничтожить это представление и повторно инициализировать его?

EDIT2:

Обнаружили ошибку. Я перестал ссылаться на loadview и viewdidload в соответствии с инструкциями jsds. И вместо этого переместил весь код в моем loadview на другую функцию, которую я вызвал из loadview. Весь этот код создает экземпляр объектов UI (initview) и помещает их в нужные места в зависимости от ориентации.

Затем я создаю еще одну функцию, которая удаляет все представления в представлении. Затем при изменении ориентации я вызываю эту функцию и свой initview, чтобы уничтожить все подпункты, а затем воссоздать их при изменении ориентации.

ответ

0

Вы никогда не должны вызывать loadView или viewDidLoad самостоятельно. Это зависит от структуры управления.

Если вы позиционируете или изменяете размеры просмотров на основе границ вида в viewDidLoad, не делайте этого. Переместите это для просмотраWillLayoutSubviews. Это будет вызываться автоматически при изменении ориентации устройства.

В качестве альтернативы используйте ограничения автоопределения, а затем вам не придется ничего делать.

+0

Извините за поздний ответ. Где можно найти документацию по этому вопросу? Я немного затрудняюсь отслеживать примеры этого. – user3009729

+0

https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/Introduction/Introduction.html https://developer.apple.com/library/ios/documentation/windowsviews/conceptual/viewpg_iphoneos/Introduction/Introduction .html https://developer.apple.com/library/ios/documentation/uikit/reference/UIViewController_Class/Reference/Reference.html – jsd

+0

Благодарим вас, особенно за ссылку, не вызывающую эти методы. Я немного неопытен в объективе c. Я исправил проблему и добавлю изменения для тех, у кого есть эта проблема. – user3009729

1

UIDeviceOrientation в основном имеет 6 разных состояний, а именно два портрета, два пейзажа и лицевой стороной вверх и вниз. Так что скажем, когда вы берете свое устройство из плоского положения в вертикальное положение, уведомление будет вызвано. Вы можете выбирать лицевой стороной вверх, вниз, и неизвестные состояния с помощью макроса UIDeviceOrientationIsValidInterfaceOrientation

UIDeviceOrientation currentOrientation = [[UIDevice currentDevice] orientation]; 

    // Ignore changes in device orientation if unknown, face up, or face down. 
    if (!UIDeviceOrientationIsValidInterfaceOrientation(currentOrientation)) { 
     return; 
    } 

Если вы до сих пор находят уведомление получать запускаемые несколько раз, я боюсь, что вы, возможно, потребуется использовать пользовательскую логику с флагами, чтобы проверить предыдущее и текущее значение.

В моем случае, так как я использую реактивные рамки какао, следующий код работает для меня:

if (IS_IPAD) { @weakify(self); [[[[[[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIDeviceOrientationDidChangeNotification object:nil] takeUntil:[self rac_willDeallocSignal]] map:^id (NSNotification *notification) { return @([[UIDevice currentDevice] orientation]); }] filter:^BOOL(NSNumber *deviceOrientationNumber) { UIDeviceOrientation currentOrientation = [deviceOrientationNumber integerValue]; //We ignore the UIDeviceOrientationUnknown, UIDeviceOrientationFaceUp and UIDeviceOrientationFaceDown return UIDeviceOrientationIsValidInterfaceOrientation(currentOrientation); }] distinctUntilChanged] subscribeNext:^(id x) { @strongify(self); //do something here... }]; }

Здесь метод distinctUntilChanged убеждается код сработал только тогда, когда ориентация меняется на новом действующий стоимость.

Смежные вопросы