UIViews ending up beneath tab bar

后端 未结 4 1574
没有蜡笔的小新
没有蜡笔的小新 2020-12-15 09:36

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

相关标签:
4条回答
  • 2020-12-15 10:12

    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:

    image

    0 讨论(0)
  • 2020-12-15 10:25

    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.

    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

    To elaborate a little more, it seems viewDidLayoutSubviews is 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.

    0 讨论(0)
  • 2020-12-15 10:26

    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.

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

    - (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;
    }
    
    0 讨论(0)
  • 2020-12-15 10:27

    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:

    @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
    
    0 讨论(0)
提交回复
热议问题