137 votes

Simulateur iOS 11 iPhone X Les icônes et les titres de la barre d'outils sont rendus en se recouvrant les uns les autres.

Quelqu'un a-t-il des problèmes avec le simulateur de l'iPhone X autour du composant UITabBar ?

Les miens semblent rendre les icônes et le titre l'un sur l'autre, je ne suis pas sûr de manquer quelque chose, je l'ai également exécuté dans le simulateur iPhone 8, et un appareil réel où il semble bien comme indiqué sur le story board.

iPhone X :

iPhone X UITabBar bug

iPhone 8

iPhone 8 UITabBar works

1 votes

Problème similaire : l'indicateur de sélection de la vue image s'enfonce dans la vue tabBar d'environ 16 points dans l'iPhone X.

0 votes

FYI - ceci n'est malheureusement pas corrigé dans Xcode 9.2beta

0 votes

C'est un bug d'uikit qui existe toujours. Les contraintes doivent être configurées correctement. Voir ma réponse ci-dessous !

41voto

David Hooper Points 503

J'ai pu contourner le problème en appelant simplement invalidateIntrinsicContentSize sur la UITabBar dans viewDidLayoutSubviews.

-(void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];
    [self.tabBar invalidateIntrinsicContentSize];
}

Remarque : le bas de la barre d'onglets devra être contenu dans le bas de la vue principale, plutôt que dans la zone sécurisée, et la barre d'onglets ne devra pas avoir de contrainte de hauteur.

0 votes

J'ai une barre d'onglets sans contrainte de hauteur, contrainte au Guide de mise en page du bas, et cela n'a pas fonctionné pour moi. Avez-vous d'autres idées ?

1 votes

Ne fonctionne pas lorsque le homeVC présente le VC A, puis rejette A, et pousse le VC B du homeVC. Il s'agit d'une solution de contournement stackoverflow.com/a/47225653/1553324

1 votes

L'ajout de cette méthode, combiné à l'épinglage de la barre d'onglets au bas de sa vue supérieure ( pas la zone de sécurité) a fonctionné pour moi.

26voto

La réponse fournie par VoidLess ne résout que partiellement les problèmes de la barre de tabulation. Il corrige les problèmes de mise en page dans la barre d'onglets, mais si vous utilisez un viewcontroller qui cache la barre d'onglets, celle-ci est rendue de manière incorrecte pendant les animations (pour la reproduire, il est préférable d'avoir 2 séquences - une modale et une push. Si vous alternez les séquences, vous pouvez voir que la barre d'onglets n'est pas rendue à sa place). Le code ci-dessous 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

0 votes

Solution complète. Merci.

4 votes

Merci pour votre réponse. Mais comment l'utiliser dans une classe UITabBarController ?

2 votes

@Jojo, étant donné la quantité de code nécessaire pour alimenter la tabbar via le code, je crée toujours uitabbarcontroller en utilisant les storyboards. Vous pouvez y affecter une classe personnalisée pour la barre d'onglets. J'espère que cela vous aidera.

22voto

Avineet Gupta Points 519

Il existe une astuce qui permet de résoudre le problème.

Il suffit de placer votre UITabBar dans un UIView.

Ça marche vraiment pour moi.

Ou vous pouvez suivre ceci Lien pour plus de détails.

3 votes

Cela a bien fonctionné, j'ai un uiview qui contient simplement la UITabBar. Placez les contraintes sur les zones sûres de l'UIView (L, R et Bottom), donnez-lui une hauteur (49) et contraignez l'UITabBar à l'UIView sur tous les côtés.

1 votes

Cette solution a fonctionné pour moi. Je n'utilisais pas un UITabController, mais seulement un UITabBar.

1 votes

Ça a marché pour moi. Merci

19voto

Cruz Points 1580

Contourner UITabBar sizeThatFits(_) pour safeArea

extension UITabBar {
    static let height: CGFloat = 49.0

    override open func sizeThatFits(_ size: CGSize) -> CGSize {
        guard let window = UIApplication.shared.keyWindow else {
            return super.sizeThatFits(size)
        }
        var sizeThatFits = super.sizeThatFits(size)
        if #available(iOS 11.0, *) {
            sizeThatFits.height = UITabBar.height + window.safeAreaInsets.bottom
        } else {
            sizeThatFits.height = UITabBar.height
        }
        return sizeThatFits
    }
}

0 votes

Brillant. Je viens de définir la taille personnalisée de ma barre d'onglets et je me demande pourquoi cela ne fonctionne pas sur l'iPhoneX. Les autres solutions ne fonctionnent pas pour moi car j'utilise le Tab Bar Controller et il n'inclut pas de contraintes.

1 votes

Il semble que cette technique ne fonctionne plus avec Xcode 12 / iOS 14.

13voto

aaannjjaa Points 170

J'ai ajouté ceci à viewWillAppear de ma coutume UITabBarController parce qu'aucune des réponses fournies n'a fonctionné pour moi :

tabBar.invalidateIntrinsicContentSize()
tabBar.superview?.setNeedsLayout()
tabBar.superview?.layoutSubviews()

1 votes

Cela m'a aidé à résoudre un problème lié au déplacement de la barre d'onglets vers le haut de l'écran. Merci !

0 votes

Mais pas pour moi :(

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X