为什么页面推动animationTabbar在iPhone X中向上移动

我创build一个应用程序Demo,使用hidesBottomBarWhenPressed隐藏TabBar中的推animation。

页面关系

但是,当我点击跳转buttonTabbar上移!? 喜欢这个: Tabbar上移

这是我的方式。声明UITabBar的子类,如ActionTabBar

迅速3,4

 class ActionTabBar: UITabBar { override var frame: CGRect { get { return super.frame } set { var tmp = newValue if let superview = self.superview, tmp.maxY != superview.frame.height { tmp.origin.y = superview.frame.height - tmp.height } super.frame = tmp } } } 

Objective-C的

 @implementation ActionTabbar - (void)setFrame:(CGRect)frame { if (self.superview && CGRectGetMaxY(self.superview.bounds) != CGRectGetMaxY(frame)) { frame.origin.y = CGRectGetHeight(self.superview.bounds) - CGRectGetHeight(frame); } [super setFrame:frame]; } @end 

VoidLess提供的答案只是部分修复了TabBar问题。 它修复了tabbar中的布局问题,但是如果你使用隐藏tabbar的viewcontroller,在animation过程中tabbar会被错误地渲染(重现它最好是2有2个segues – 一个模式和一个push,如果你改变了segues,你可以看到tabbar被排除在外)。 看到解决这两个问题的代码。 干得好苹果。

 class SafeAreaFixTabBar: UITabBar { var oldSafeAreaInsets = UIEdgeInsets.zero @available(iOS 11.0, *) override func safeAreaInsetsDidChange() { super.safeAreaInsetsDidChange() if oldSafeAreaInsets != safeAreaInsets { oldSafeAreaInsets = safeAreaInsets invalidateIntrinsicContentSize() superview?.setNeedsLayout() superview?.layoutSubviews() } } override func sizeThatFits(_ size: CGSize) -> CGSize { var size = super.sizeThatFits(size) if #available(iOS 11.0, *) { let bottomInset = safeAreaInsets.bottom if bottomInset > 0 && size.height < 50 && (size.height + bottomInset < 90) { size.height += bottomInset } } return size } override var frame: CGRect { get { return super.frame } set { var tmp = newValue if let superview = superview, tmp.maxY != superview.frame.height { tmp.origin.y = superview.frame.height - tmp.height } super.frame = tmp } } } } 

Objective-C代码:

 @implementation VSTabBarFix { UIEdgeInsets oldSafeAreaInsets; } - (void)awakeFromNib { [super awakeFromNib]; oldSafeAreaInsets = UIEdgeInsetsZero; } - (void)safeAreaInsetsDidChange { [super safeAreaInsetsDidChange]; if (!UIEdgeInsetsEqualToEdgeInsets(oldSafeAreaInsets, self.safeAreaInsets)) { [self invalidateIntrinsicContentSize]; if (self.superview) { [self.superview setNeedsLayout]; [self.superview layoutSubviews]; } } } - (CGSize)sizeThatFits:(CGSize)size { size = [super sizeThatFits:size]; if (@available(iOS 11.0, *)) { float bottomInset = self.safeAreaInsets.bottom; if (bottomInset > 0 && size.height < 50 && (size.height + bottomInset < 90)) { size.height += bottomInset; } } return size; } - (void)setFrame:(CGRect)frame { if (self.superview) { if (frame.origin.y + frame.size.height != self.superview.frame.size.height) { frame.origin.y = self.superview.frame.size.height - frame.size.height; } } [super setFrame:frame]; } @end 

声明NavigationController的子类

  @implementation XXNavigationController - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated { [super pushViewController:viewController animated:animated]; CGRect frame = self.tabBarController.tabBar.frame; frame.origin.y = [UIScreen mainScreen].bounds.size.height - frame.size.height; self.tabBarController.tabBar.frame = frame; } 

我会提供这个错误的另一个解决scheme(似乎苹果)。

解决办法不是禁止tabbar向上移动,而是让tabbar向上移动时不显示黑色区域

核心的事情是添加一个子视图到你的视图控制器,因为它最深的子视图,这个子视图的框架是窗口的大小。所以当tabbar上移时,这个子视图将显示,而不是黑色区域

 if (@available(iOS 11.0, *)) { UIView* bgView = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds]; bgView.autoresizingMask = UIViewAutoresizingNone; bgView.backgroundColor = UIColorFromRGB(0xefeff4); [self.view addSubview:bgView]; } 

此方法的便利性是您不必子类化tabbar或覆盖navigationcontroller的推送方法

这个问题似乎固定在iOS 11.2

只需要将特定于iPhone X的启动图像添加到资产目录(因为它使用@ 3x)的大小为1125 x 2436。

我希望这会解决你的问题。