在我的应用中,我使用autolayout将标签量与bottomLayoutGuide对齐。当应用程序第一次启动时,所有内容都按照我的要求进行了布局,但是当我切换标签并返回时,标签已经消失在标签栏控制器下面。
如果我旋转设备,横向视图会正确显示,当我将其旋转回纵向时,视图将恢复正常。我似乎无法弄清楚导致这种行为的原因。谢谢你的帮助!
答案 0 :(得分:18)
这是由于iOS7中的错误导致的,其中底部布局指南错误地设置为高度0而不是标签栏的高度。旋转设备时,底部布局指南设置正确。
目前,您最好的选择是禁用底部扩展布局:
- (UIRectEdge)edgesForExtendedLayout
{
return [super edgesForExtendedLayout] ^ UIRectEdgeBottom;
}
对于从标签栏控制器显示的每个视图控制器执行此操作。请记住将标签栏视图控制器的背景颜色设置为适合您应用的颜色。
确保在https://bugreport.apple.com
打开错误报告再详细说明,在切换视图控制器时,似乎viewDidLayoutSubviews
被调用了两次。第一次,一切都设置正确,但第二次底部布局指南高度为0.您可以从堆栈跟踪中看到第一个来自标签栏布局,而第二个调用是来自预定的CALayer布局,这是不正确的
答案 1 :(得分:14)
虽然Leo的答案显示了如何以编程方式执行此操作,但如果要从界面构建器执行此操作,请选择View Controller并从“Extend Edges”部分取消选中“Under bottom bars”:
答案 2 :(得分:5)
调用setNeedsLayout就是所有需要完成的事情。这基本上修补了框架错误。当选择新视图时,需要在UITabBarController视图上调用它。为应用程序的标签栏控制器创建一个委托。并将其放在委托对象中:
@interface MyPatch : NSObject <UITabBarControllerDelegate>
@end
@implementation MyPatch
-(void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
{
[tabBarController.view setNeedsLayout];
}
@end
并在任何地方初始化它......就像这样:
@interface AppDelegate : UIResponder <UIApplicationDelegate>
{
MyPatch *patch;
}
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
patch=[MyPatch new];
myTabBarController.delegate=patch;
}
@end
答案 3 :(得分:0)
Leo是对的,bottomLayoutGuide返回不正确。
但是,取消设置扩展边栏下方(或覆盖edgesForExtendedLayout
)对我的其他子视图有太多不受欢迎的影响。
如果您想根据底部布局指南仅更改一个视图的约束,
实现viewWillLayoutSubviews
并检查bottomLayoutGuide
属性的值,并根据需要调整该约束,如下所示:
- (void)viewWillLayoutSubviews {
[self adaptBottomLayoutGuides];
}
/// Workaround for iOS7 bug returning wrong bottomLayoutGuide length if this is 1st tab in TabViewController
- (void)adaptBottomLayoutGuides {
NSLog(@"%f", self.bottomLayoutGuide.length);
CGFloat expectedHeight = 123;
CGFloat adaptedSpacing = expectedHeight - self.bottomLayoutGuide.length;
self.viewBottomLayoutSpacingConstrain.constant = adaptedSpacing;
}