【问题标题】:UIViews ending up beneath tab barUIViews 在标签栏下方结束
【发布时间】:2013-10-26 17:43:33
【问题描述】:

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

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

【问题讨论】:

  • 您是在代码中还是在 StoryBoard 中这样做的?

标签: ios xcode ios7 autolayout


【解决方案1】:

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

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

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

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

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

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

【讨论】:

  • 我在 iOS8 上遇到了同样的问题。但是当我实现解决方案并禁用底部扩展布局时,如果我改变方向,或者退出视图控制器并再次输入,底部扩展布局实际上将是正确的尺寸和标签栏高度。
  • 是的,这个错误在 iOS 8.2 中仍然存在。将设备旋转到横向,然后再转回纵向,解决了这个问题。
  • 我在 iOS 8.3 上,bug 仍然存在。
  • 伙计们,请务必打开 Apple 的错误报告。
  • 我在 9.3 上仍然出现错误
【解决方案2】:

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

【讨论】:

    【解决方案3】:

    只需调用 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
    

    【讨论】:

    • 这个解决方案在我看来是最好的一个。选择不按照@Steve 的建议扩展选项卡栏下的视图会导致透明度效果丢失。 @Ben 提到的布局传递可以直接在选项卡中包含的视图控制器中触发,无需委托。标签栏控制器是一个可选属性,因此您可以在视图控制器自己的视图上调用tabBarController.setNeedsLayout(),然后调用view.layoutIfNeeded()。这解决了我在 iOS 9 中的问题
    【解决方案4】:

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

    【讨论】:

      猜你喜欢
      • 2022-09-26
      • 1970-01-01
      • 2022-01-18
      • 2019-08-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多