【问题标题】:Trying to understand how shouldAutorotateToInterfaceOrientation and UIDeviceOrientationDidChangeNotification试图了解 shouldAutorotateToInterfaceOrientation 和 UIDeviceOrientationDidChangeNotification 如何
【发布时间】:2012-03-19 19:40:48
【问题描述】:

我有一个想要横向启动的界面。启动后,当用户将设备旋转为纵向时,我正在显示一个日视图日历。返回横向时,日历将被关闭。一切都很好,我的应用程序用户界面在横向方向正确显示,日历在纵向方向正确显示。

问题在于,如果用户在启动时将 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;  
        }            
    }
}

【问题讨论】:

    标签: iphone xcode device-orientation


    【解决方案1】:

    我找到了解决问题的方法。在 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];
    
    }
    

    【讨论】:

    • 我将在允许时将其标记为已回答。然而,仍然很好奇,为什么 shouldAutorotateToInterfaceOrientation 和 UIDeviceOrientationDidChangeNotification 方法在启动时会触发两次,一次是横向设备方向,一次是纵向设备方向,即使用户拿着设备纵向。他们为什么要开火?设备尚未旋转。我现在猜测可能是因为我在横向模式下使用状态栏启动界面并且设备处于纵向,这被检测为旋转。这并不能解释为什么它会触发两次。
    【解决方案2】:

    我不会生成 beginGeneratingDeviceOrientationNotifications,

    一种简单的方法是使用 BOOL 来检查何时允许进入肖像 shouldAutorotateToInterfaceOrientation

    类似这样的:

    - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {       
    
        if ((interfaceOrientation == UIDeviceOrientationPortrait)|| (interfaceOrientation == UIDeviceOrientationPortraitUpsideDown)) {   
    
            return portraitIsAllowed;
        } 
    
        return YES;
    }
    

    然后在需要时在其他方法中更改它。

    请记住,每次用户旋转设备以及首次加载(实例化)控制器时都会调用 shouldAutorotateToInterfaceOrientation

    【讨论】:

    • 好的,接受您的建议,我将所有内容移至 shouldAutoRatateToInterfaceOrientation。基本上我有同样的问题。如果用户在启动时以纵向模式持有设备。 shouldAutoRotate 触发时 UIInterfaceOrientation 设置为横向,这会将我的初始化布尔值重置为 false,然后触发设置为纵向,因为现在初始化为 false,因此会触发我的日历例程。除非用户实际将设备从横向旋转到纵向,否则我不想要日历。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-13
    相关资源
    最近更新 更多