web-dev-qa-db-fra.com

Pourquoi la barre de tabulation d'animation Push de page monte dans l'iPhone X

Je crée une démo d'application, j'utilise hidesBottomBarWhenPushed hide Tabbar dans Push Animation.

Page Relationship

Mais, quand je clique sur la barre d'onglets du bouton Jump, montez !? comme ça: Tabbar Move up

31
Tommy

La réponse fournie par VoidLess ne résout les problèmes de TabBar que partiellement. Il corrige les problèmes de mise en page dans la barre de tabulations, mais si vous utilisez le contrôleur de vue qui masque la barre de tabulations, la barre de tabulations est rendue incorrectement pendant les animations (pour la reproduire, il est préférable que 2 aient 2 séquences - une modale et une push. Si vous alternez les séquences, vous pouvez voir la barre de tabulations être déplacé). Voir le code ci-dessous qui résout les deux problèmes. Bon travail 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
        }
    }
}
}

Code 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
14

C'est ma façon。 Déclarer une sous-classe de UITabBar, comme 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
        }
    }
}

Objectif 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
9
xu tong

Déclarez une sous-classe de 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;
    }
2
sukeyang

Edit: Après la sortie de 12.1.1, ce problème a été corrigé. Vous pouvez conserver la structure d'origine.


Si vous changez votre structure de

UITabBarController -> UINavigationController -> UIViewController

à

UINavigationController -> UITabBarController -> UIViewController

vous constaterez que ce problème a été résolu. Je ne sais vraiment pas pourquoi Apple ne résout pas ce problème.

Dans iOS 12.1, ce problème devient plus grave. Vous pouvez voir le texte TabBar sauter au-dessus de TabBar à chaque fois, si vous utilisez le geste pour revenir en arrière.

Note: Cette façon peut certainement résoudre ce problème, mais je ne sais pas si c'est une bonne idée. De plus, si votre structure est assez compliquée, vous devez changer beaucoup de choses.

2
Jeff Zhang

je vais fournir une autre solution pour ce bug (semble Apple fait).

et la solution n'est pas d'interdire la barre de tabulation de monter, mais de faire en sorte que la zone noire ne s'affiche pas lorsque la barre de tabulation monte

l'essentiel est d'ajouter une sous-vue à votre viewcontroller car elle est la sous-vue la plus profonde et le cadre de cette sous-vue est la taille de la fenêtre.

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

}

la commodité de cette méthode est que vous n'aurez pas à sous-classer la barre d'onglets ni à écraser la méthode Push du contrôleur de navigation

0
ximmyxiao