繁体   English   中英

UINavigationController工具栏和设备方向(旋转)

[英]UINavigationController Toolbar and device orientation (rotation)

因此,我有一个带有这样的嵌套设置的iPhone应用程序:[RootViewController]-> [UITabBarController]-> [UINavigationController]-> [subViewControllers]。 一切都是以编程方式构建的,而不是在Interface Builder中构建的。

我只是试图支持所有设备方向。 我所有的AutoResizing蒙版均已设置好,一切旋转并根据需要进行扩展/收缩。 除了NavigationController的navBar和Toolbar之外的所有内容。 (通常,这些视图会根据方向自动自动调整大小。即,在横向模式下,导航栏和工具栏应自动调整为大约32px,在Portrai模式下则自动调整为44px。)奇怪的是,导航控制器的subView正在调整大小,但是实际的navBar和工具栏不是。 换句话说,无论导航栏和工具栏的大小如何,内容在任何方向上的拉伸/收缩都约为12像素左右。 这似乎是自动调整大小的蒙版正在执行的工作。

因此,为了尝试解决这种情况,我为UINavigationController创建了一个类别,该类别响应“ willRotateToInterfaceOrientation:duration:”以触发“ sizeToFit”选择器。 (这项技术来自Stack Overflow上的另一篇文章,也有类似的问题。)在研究中,我发现只有最外层的视图控制器会收到此消息,因此,我的根视图控制器在tab控制器上将此称为“依次在nav控制器等上调用它。这解决了这个问题,现在当旋转外部视图时,我的嵌套视图控制器将收到通知。 使用sizeToFit技术,导航栏和工具栏都可以自行调整大小。 但是,仍然存在重新定位工具栏的问题,以弥补尺寸更改带来的偏移。 (因为我们在iPhone中的视图坐标从左上角开始。)

在willRotate方法中进行此操作很棘手的原因是,我们无法知道新的边界视图维将是什么,也无法知道当前的方向。 (除非您打开deviceOrientationNotifications,否则我不会。)我们要做的就是设置新的方向,以及工具栏的当前帧值。 我可以对此进行硬编码,并使用一张草稿纸以老式的方式计算框架调整,但是我真的想保留动态视图调整功能,而无需对设备的屏幕尺寸做任何假设。

因此,通过使用以下代码,我设法通过简单地将工具栏“相对于”它变成的大小“撞”了12px来解决这个问题。 为了防止用户翻转设备时发生过度颠簸,我使用当前工具栏的框架高度导出当前方向。 (这意味着我仍在对工具栏的前后大小进行假设,但是我对此感觉更好,因为我可以将其影响到一定程度,而不是尝试以编程方式调整设备的物理屏幕大小。)

@implementation UINavigationController (BLUINavigationControllerAutoRotate)

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
    return TRUE;
}

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];

    // Resize the navBar
    [[self navigationBar] performSelector:@selector(sizeToFit)
                               withObject:nil
                               afterDelay:(0.5f * duration)];

    // Read our current frame size
    CGRect toolbarFrame = self.toolbar.frame;

    // Prevent over adjusting when flipping the device
    if ((toolbarFrame.size.height < 38
         && (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft
             || toInterfaceOrientation == UIInterfaceOrientationLandscapeRight))
        || (toolbarFrame.size.height > 38
            && (toInterfaceOrientation == UIInterfaceOrientationPortrait
                || toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)))
    {
        // We are already resized and repositioned.
        return;
    }

    // Calculate and apply the toolbar offset
    const NSInteger delta = 12;     // the difference in size between 44 and 32 px.
    toolbarFrame.origin.y += ((toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft)
                              || (toInterfaceOrientation == UIInterfaceOrientationLandscapeRight)) ? (delta) : (-delta);
    self.toolbar.frame = toolbarFrame;

    // Resize the toolbar
    [[self toolbar] performSelector:@selector(sizeToFit)
                         withObject:nil
                         afterDelay:(0.5f * duration)];

}

@end

因此,现在我已经正确地使用了NavigationBar和Toolbar。 最终用户永远不会知道我必须实施所有这些额外的变通方法才能重新启用似乎是标准行为的功能。 所以我的问题是,为什么我必须做所有这一切? 有没有我应该知道的更好的方法,或者我根本不在其他地方做的事情? (即[navigationController setAutomaticallyResizesToolbarOnRotate:TRUE];或类似的东西?)就像我说的那样,这似乎应该预先连接好,所以对我来说,不得不拖延转发消息和强制触发,这就像是过度设计的黑客一样而不是正确的解决方案。

谢谢!

您正在将rootRotateToInterfaceOrientation消息从您的根视图控制器传递到选项卡视图控制器-为什么不传递所有其他旋转消息,看看是否有帮助?

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
    [tabBarController willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
}

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
    [tabBarController willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
}

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation  {
    [super didRotateFromInterfaceOrientation:toInterfaceOrientation];
    [tabBarController didRotateFromInterfaceOrientation:toInterfaceOrientation];
}

- (void)willAnimateFirstHalfOfRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    [super willAnimateFirstHalfOfRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
    [tabBarController willAnimateFirstHalfOfRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
}

- (void)didAnimateFirstHalfOfRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
    [super didAnimateFirstHalfOfRotationToInterfaceOrientation:toInterfaceOrientation];
    [tabBarController didAnimateFirstHalfOfRotationToInterfaceOrientation:toInterfaceOrientation];
}

- (void)willAnimateSecondHalfOfRotationFromInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    [super willAnimateSecondHalfOfRotationFromInterfaceOrientation:toInterfaceOrientation duration:duration];
    [tabBarController willAnimateSecondHalfOfRotationFromInterfaceOrientation:toInterfaceOrientation duration:duration];
}

如果您将所有这些都传递给选项卡栏控制器,我会很感兴趣-您的问题似乎应该自动发生,而不是您做的所有额外工作!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM