xcode UIViews 在标签栏下方结束

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19440197/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 04:07:09  来源:igfitidea点击:

UIViews ending up beneath tab bar

iosxcodeios7autolayout

提问by Connor

In my app, I aligned a label the standard amount from the bottomLayoutGuide using autolayout. When the app first starts everything is layed out as I wanted but when I switch tabs and go back the label has disappeared under the tab bar controller.

在我的应用程序中,我使用自动布局将一个标签与 bottomLayoutGuide 中的标准数量对齐。当应用程序第一次启动时,一切都按照我想要的方式布置,但是当我切换标签并返回时,标签在标签栏控制器下消失了。

If I rotate the device, the landscape view appears correctly and when I rotate it back to portrait the view is back to normal. I can't seem to figure out what is causing this behavior. Thanks for your help!

如果我旋转设备,横向视图会正确显示,当我将其旋转回纵向视图时,视图会恢复正常。我似乎无法弄清楚是什么导致了这种行为。谢谢你的帮助!

回答by Leo Natan

This happens due to a bug in iOS7, where the bottom layout guide is incorrectly set to height 0 instead of the tab bar's height. When you rotate the device, the bottom layout guide is set correctly.

这是由于 iOS7 中的一个错误,底部布局指南错误地设置为高度 0 而不是标签栏的高度。旋转设备时,底部布局指南设置正确。

Currently, your best option is to disable bottom extended layout:

目前,您最好的选择是禁用底部扩展布局:

- (UIRectEdge)edgesForExtendedLayout
{
    return [super edgesForExtendedLayout] ^ UIRectEdgeBottom;
}

Do this for each view controller that is displayed from the tab bar controller. Remember to set the tab bar view controller's background color to whatever suits your application.

对从标签栏控制器显示的每个视图控制器执行此操作。请记住将标签栏视图控制器的背景颜色设置为适合您的应用程序的任何颜色。

Make sure to open a bug report at https://bugreport.apple.com

确保在https://bugreport.apple.com上打开错误报告

To elaborate a little more, it seems viewDidLayoutSubviewsis called twice when switching view controllers. First time, everything is set correctly, but the second time bottom layout guide height is 0. You can see from the stack trace that the first one comes from tab bar layout, while the second call is from a scheduled CALayer layout, which is incorrect.

更详细地说,它似乎viewDidLayoutSubviews在切换视图控制器时被调用了两次。第一次,一切都设置正确,但是第二次底部布局指南高度为0。从堆栈跟踪中可以看出,第一个来自tab bar布局,而第二个调用来自预定的CALayer布局,这是不正确的.

回答by steve

While Leo's answer shows how to do it programmatically, if you want to do this from the interface builder, select your View Controller and uncheck "Under bottom bars" from the Extend Edges section:

虽然 Leo 的回答显示了如何以编程方式执行此操作,但如果您想从界面构建器中执行此操作,请选择您的视图控制器并从“扩展边缘”部分取消选中“底部栏下方”:

image

图片

回答by Ben

Calling setNeedsLayout is all that needs to be done. This essentially patches the framework bug. It needs to be called on the UITabBarController view itself when a new view is selected. Create a delegate for the app's tab bar controller. and put this in the delegate object:

只需调用 setNeedsLayout 即可。这基本上修补了框架错误。It needs to be called on the UITabBarController view itself when a new view is selected. 为应用程序的标签栏控制器创建一个委托。并将其放入委托对象中:

@interface MyPatch : NSObject <UITabBarControllerDelegate>

@end

@implementation MyPatch

-(void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
{
    [tabBarController.view setNeedsLayout];
}

@end

And initialize it wherever you want... something like this:

并在任何你想要的地方初始化它......像这样:

@interface AppDelegate : UIResponder <UIApplicationDelegate>
{
         MyPatch *patch;

}

@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    patch=[MyPatch new];
    myTabBarController.delegate=patch;
}

@end

回答by Christopher Gretzki

Leo is right, the bottomLayoutGuide is returned incorrectly. But unsetting the extend edges under bottom bars(or overriding edgesForExtendedLayout) had too much undesired effects on other subviews for me.

Leo 是对的,bottomLayoutGuide 返回错误。但是取消设置底部栏(或覆盖edgesForExtendedLayout延伸边缘对我来说对其他子视图有太多不良影响。

If you want to change only the constraint for one view according to the bottom layout guide, implement viewWillLayoutSubviewsand check the value of the bottomLayoutGuideproperty and adapt that one constraint if required, like so:

如果您只想根据底部布局指南更改一个视图的约束,请实现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;
}