Попытка понять, как следуетAutorotateToInterfaceOrientation и UIDeviceOrientationDidChangeNotification - PullRequest
0 голосов
/ 01 марта 2012

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

Проблема в том, что пользователь при запуске держит iPhone в горизонтальной ориентации. Что бы я ни делал, я не могу запустить его с моим пользовательским интерфейсом в ландшафтном режиме. Мой метод UIDeviceOrientationDidChangeNotification запускается дважды, первый раз [UIDevice currentDevice] .orientation - альбомная, а вторая - портретная. Конечный результат - пользовательский интерфейс поворачивается в портретный режим и отображает дневной вид. Не то, что я хочу. Я хочу, чтобы пользовательский интерфейс оставался в горизонтальной ориентации, пока пользователь физически не повернет устройство из альбомной в портретную ориентацию.

Я не понимаю, почему оно срабатывает с альбомной ориентацией [UIDevice currentDevice] .orientation, когда пользователь держит устройство в портретной ориентации.

Вот как выглядит мой код в viewController ...

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {       

    if ((interfaceOrientation == UIDeviceOrientationPortrait)|| (interfaceOrientation == UIDeviceOrientationPortraitUpsideDown)) {            
        return NO;
    } 

    return YES;
}


- (void)viewDidLoad {
    [super viewDidLoad];
        showingCalendar = NO;
        initializing=YES;
        [[UIDevice currentDevice]    beginGeneratingDeviceOrientationNotifications];
        [[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(didRotate:)
                                             name:UIDeviceOrientationDidChangeNotification
                                           object:nil];

}

-(void)didRotate:(NSNotification *)notification {
    UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;  
    if ((deviceOrientation == UIDeviceOrientationPortrait) || (deviceOrientation == UIDeviceOrientationPortraitUpsideDown))  {            
        if ((!showingCalendar) && (!initializing)) {
            showingCalendar = YES;
            [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:YES];            
            GCCalendarPortraitView *calendar = [[[GCCalendarPortraitView alloc] init] autorelease];
            navigationController = [[UINavigationController alloc] initWithRootViewController:calendar];
            [self presentModalViewController:navigationController animated:YES];
        }
    }else if ((deviceOrientation == UIDeviceOrientationLandscapeRight) || (deviceOrientation == UIDeviceOrientationLandscapeLeft)) {
        if (showingCalendar) {
            showingCalendar = NO;
            if (deviceOrientation == UIDeviceOrientationLandscapeRight){
                [self dismissModalViewControllerAnimated:YES];
            }else if (deviceOrientation == UIDeviceOrientationLandscapeLeft){
                [self dismissModalViewControllerAnimated:YES];
            }
        }else {
            initializing = NO;  
        }            
    }
}

Ответы [ 2 ]

1 голос
/ 01 марта 2012

Я нашел решение моей проблемы.В viewDidLoad я запустил scheduleTimerWithTimeInterval и переместил beginGeneratingDeviceOrientationNotifications в метод выбора.

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

Вот мой модифицированный код.Все остальное осталось прежним ...

- (void)viewDidLoad {
    [super viewDidLoad];
    showingCalendar = NO;
    initializing=YES;
    timer =  [NSTimer scheduledTimerWithTimeInterval:.55 target:self selector:@selector(startOrientationNotifications) userInfo:nil repeats: NO];

}


-(void)startOrientationNotifications {
    [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(didRotate:)
                                             name:UIDeviceOrientationDidChangeNotification
                                           object:nil];

}
0 голосов
/ 01 марта 2012

я бы не сгенерировал beginGeneratingDeviceOrientationNotifications,

простым способом было бы использовать BOOL для проверки, когда портрет разрешен в shouldAutorotateToInterfaceOrientation

примерно так:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {       

    if ((interfaceOrientation == UIDeviceOrientationPortrait)|| (interfaceOrientation == UIDeviceOrientationPortraitUpsideDown)) {   

        return portraitIsAllowed;
    } 

    return YES;
}

затем просто измените его, когда это необходимо в других методах.

И имейте в виду, что shouldAutorotateToInterfaceOrientation вызывается каждый раз, когда пользователь поворачивает устройство И также когда вы загружаете (создаете экземпляр) свой контроллер в первый раз

...