所以我有这个iPhone应用程序,嵌套设置如下: [RootViewController的] - GT;的UITabBarController] - GT;的UINavigationController] - GT; [subViewControllers]。一切都是以编程方式构建的,而不是在Interface Builder中构建的。
我只是想支持所有设备方向。我的所有AutoResizing蒙版都已设置好,所有内容都会根据需要旋转和扩展/收缩。除了NavigationController的navBar和工具栏之外的所有东西。 (通常,这些视图会根据方向自动调整大小。即在横向上,导航栏和工具栏应自动调整为大约32px,并在Portrai模式下调整为44px。)特别之处在于导航控制器的子视图正在调整大小,但是实际的navBar和工具栏不是。换句话说,内容在任何方向上拉伸/缩小大约12 px,就像导航栏和工具栏调整大小一样。这似乎是自动化面具正在发挥作用。
因此,为了尝试解决这种情况,我为UINavigationController创建了一个类别,它响应'willRotateToInterfaceOrientation:duration:'以触发'sizeToFit'选择器。 (这个技术来自Stack Overflow上的另一个帖子,有类似的问题。)我发现,在我的研究中,只有最外层的视图控制器收到此消息,所以我让我的根视图控制器在选项卡控制器上调用它,反过来在导航控制器等上调用它。这解决了这个问题,现在我的嵌套视图控制器在外部视图旋转时得到通知。使用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];或类似的东西?)就像我说的,这似乎是预先连线的,所以对于我来说,必须使用转发消息和强制触发器的finagle感觉就像一个过度设计的黑客而不是正确的解决方案。
谢谢!
答案 0 :(得分:3)
您正在从根视图控制器向选项卡视图控制器传递willRotateToInterfaceOrientation消息 - 为什么不传递所有其他轮换消息并查看是否有帮助?即。
- (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];
}
我有兴趣看看如果你将所有这些传递给标签栏控制器会发生什么 - 你的问题似乎应该是自动发生的事情,而不是你所做的所有额外工作!