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

Iphone UINavigationController工具栏和设备方向(旋转),iphone,uinavigationcontroller,uitoolbar,autorotate,autoresizingmask,Iphone,Uinavigationcontroller,Uitoolbar,Autorotate,Autoresizingmask,我有一个iPhone应用程序,它的嵌套设置如下: [RootViewController]->[UITabBarController]->[UINavigationController]->[SubViewController]。所有内容都是以编程方式构建的,而不是在Interface Builder中 我只是尝试支持所有设备方向。我所有的自动调整大小的遮罩都设置好了,所有的东西都会根据需要旋转和展开/收缩。除了NavigationController的导航栏和工具栏之外的所有内容。(通常情况下

我有一个iPhone应用程序,它的嵌套设置如下: [RootViewController]->[UITabBarController]->[UINavigationController]->[SubViewController]。所有内容都是以编程方式构建的,而不是在Interface Builder中

我只是尝试支持所有设备方向。我所有的自动调整大小的遮罩都设置好了,所有的东西都会根据需要旋转和展开/收缩。除了NavigationController的导航栏和工具栏之外的所有内容。(通常情况下,这些视图会根据方向自动调整大小。例如,在横向模式下,导航栏和工具栏应自动调整大小至约32px,在Portrai模式下为44px。)奇怪的是,导航控制器的子视图正在调整大小,但实际的导航栏和工具栏没有。换句话说,内容在任意方向上拉伸/收缩约12 px左右,就好像导航栏和工具栏的大小已调整一样。这似乎是自动调整大小的遮罩在起作用

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

在willRotate方法中,这一点很棘手,因为我们无法知道新的边界视图维度是什么,也不知道当前的方向是什么。(除非你打开了deviceOrientationNotifications,我没有)我们需要做的就是新的方向是什么,以及工具栏的当前帧值是什么。我可以用一张草稿纸来硬编码并计算帧调整,但我真的想保留动态视图大小调整功能,而不必对设备的屏幕尺寸做任何假设

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

@实现UINavigationController(BLUINavigationControllerAutoRotate)
-(布尔)应将自动旋转指针面方向:(UIInterfaceOrientation)转换为接口方向
{
返回TRUE;
}
-(无效)将旋转到接口方向:(UIInterfaceOrientation)到接口方向持续时间:(NSTimeInterval)持续时间
{
[super Will RotateToInterfaceOrientation:toInterfaceOrientation持续时间:持续时间];
//调整导航栏的大小
[[self-navigationBar]性能选择器:@selector(sizeToFit)
withObject:零
后延迟:(0.5f*持续时间)];
//读取我们当前的帧大小
CGRect toolbarFrame=self.toolbar.frame;
//防止翻转设备时过度调整
如果((工具栏框.尺寸.高度<38
&&(toInterfaceOrientation==UIInterfaceOrientationAndscapeLeft
||toInterfaceOrientation==UIInterfaceOrientationAndscapeRight)
||(工具栏frame.size.height>38
&&(toInterfaceOrientation==UIInterfaceOrientation纵向
||toInterfaceOrientation==UIInterfaceOrientation肖像向上向下)
{
//我们已经调整了大小并重新定位。
返回;
}
//计算并应用工具栏偏移量
const NSInteger delta=12;//44和32 px之间的大小差异。
toolbarFrame.origin.y+=((toInterfaceOrientation==UIInterfaceOrientationAndscapeLeft)
||(toInterfaceOrientation==UIInterfaceOrientationAndscapeRight))?(增量):(-delta);
self.toolbar.frame=toolbarFrame;
//调整工具栏的大小
[[self toolbar]性能选择器:@selector(sizeToFit)
withObject:零
后延迟:(0.5f*持续时间)];
}
@结束
现在,我已经正确地操作了导航栏和工具栏。最终用户永远不会知道,为了重新启用似乎应该是标准行为的行为,我必须实现所有这些额外的工作。所以我的问题是,为什么我要这么做?有没有更好的方法我应该知道,或者我只是在其他地方没有做的事情?(例如,[navigationController setAutomaticallyResizesToolbarOnRotate:TRUE];或者类似的东西?)就像我说的,这看起来像是预连线的,所以对我来说,不得不处理转发消息和强制触发器感觉像是过度设计的黑客行为,而不是正确的解决方案


谢谢

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

- (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];
}

我很想看看如果你把所有这些都传递给你的标签栏控制器会发生什么-你的问题似乎应该自动发生,而不是你所做的所有额外工作

你在传遗嘱
- (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];
}