Why page Push animation Tabbar moving up in the iPhone X Why page Push animation Tabbar moving up in the iPhone X ios ios

Why page Push animation Tabbar moving up in the iPhone X


Answer provided by VoidLess fixes TabBar problems only partially. It fixes layout problems within tabbar, but if you use viewcontroller that hides tabbar, the tabbar is rendered incorrectly during animations (to reproduce it is best 2 have 2 segues - one modal and one push. If you alternate the segues, you can see tabbar being rendered out of place). See the code bellow that fixes both of the problems. Good job apple.

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 code:

@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


This is my way。 Declare a subclass of UITabBar, such as ActionTabBar

swift 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


Declare a subclass of 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;    }