Почему страница Push-анимация Tabbar движется вверх в iPhone X

Я создаю приложение Demo, используйте hidesBottomBarWhenPushed hide Tabbar в Push Animation.

Page Relationship

Но, когда я нажимаю Tabbar Tabbar вверх!? как это: Tabbar Move up

Ответ 1

Ответ, предоставленный VoidLess, исправляет проблемы TabBar только частично. Он исправляет проблемы с макетами на вкладке, но если вы используете viewcontroller, который скрывает вкладку, вкладка отображается неправильно во время анимации (для воспроизведения лучше всего 2 имеют 2 segues - один модальный и один нажатие. Если вы чередуете segues, вы можете увидеть вкладку будучи неуместным). См. Приведенный ниже код, который устраняет обе проблемы. Хорошая работа яблока.

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

Ответ 2

Это мой путь. Объявите подкласс UITabBar, например 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

Ответ 3

Объявить подкласс 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;
    }

Ответ 4

Изменение: после выпуска 12.1.1 эта проблема исправлена. Вы можете сохранить исходную структуру.


Если вы измените структуру

UITabBarController -> UINavigationController -> UIViewController

в

UINavigationController -> UITabBarController -> UIViewController

вы обнаружите, что эта проблема решена. Я действительно не знаю, почему Apple не исправляет эту проблему.

В iOS 12.1 эта проблема становится более серьезной. Вы можете видеть, как текст TabBar перепрыгивает выше TabBar каждый раз, если вы используете жест, чтобы вернуться назад.

Примечание. Этот способ может решить эту проблему, но я не уверен, хорошая ли это. Кроме того, если ваша структура довольно сложная, вам нужно изменить много вещей.

Ответ 5

Я предоставил другое решение для этой ошибки (кажется, сделанное яблоком).

и решение не должно запрещать перемещение табуляции вверх, но чтобы черная область не отображалась при продвижении панели вверх

ядро ​​добавляет subview к вашему viewcontroller, поскольку он является самым глубоким subview, и этот кадр представления представляет собой размер окна. Когда табуляция перемещается вверх, это подвью будет показано вместо черной области

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

}

удобство этого метода заключается в том, что вам не придется подклассифицировать вкладку или перезаписывать метод pushcontroller

Ответ 6

эта проблема кажется исправленной в iOS 11.2

Ответ 7

Просто нужно добавить образ запуска специально для iPhone X в каталог активов (потому что он использует @3x) размером 1125 x 2436.

Я надеюсь, что это решит вашу проблему.