31

我构建了一个应用 Demo,在 Push Animation 中使用 hidesBottomBarWhenPushed 隐藏 Tabbar。

页面关系

但是,当我点击跳转按钮标签栏向上移动!?像这样: 标签栏上移

4

7 回答 7

14

VoidLess 提供的答案仅部分修复了 TabBar 问题。它修复了标签栏内的布局问题,但是如果您使用隐藏标签栏的视图控制器,则标签栏在动画期间渲染不正确(重现它最好 2 有 2 个转场 - 一个模式和一个推送。如果您交替转场,您可以看到标签栏被渲染不合适)。请参阅下面修复这两个问题的代码。干得好苹果。

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
于 2017-11-10T15:01:47.190 回答
9

这是我的方式。声明一个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
于 2017-09-26T08:49:57.003 回答
2

声明 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;
    }
于 2017-10-18T06:07:29.270 回答
2

编辑:12.1.1发布后,此问题已得到修复。您可以保留原始结构。


如果你改变你的结构

UITabBarController -> UINavigationController -> UIViewController

UINavigationController -> UITabBarController -> UIViewController

你会发现这个问题已经解决了。我真的不知道为什么苹果不解决这个问题。

在 iOS 12.1 中,这个问题变得更加严重。如果您使用手势弹回,您可以看到 TabBar 文本每次跳到 TabBar 上方。

注意:这种方式肯定可以解决这个问题,但我不确定它是否是一个好主意。另外,如果你的结构很复杂,你需要改变很多东西。

于 2018-11-01T00:45:06.613 回答
0

我将为这个错误提供另一种解决方案(似乎是苹果制造的)。

解决方法不是禁止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 的 push 方法

于 2017-11-23T06:39:58.920 回答
-4

这个问题似乎在 iOS 11.2 中已修复

于 2017-12-26T03:17:10.230 回答
-5

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

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

于 2017-10-04T09:54:07.793 回答