web-dev-qa-db-fra.com

Ombre sombre sur la barre de navigation pendant la transition de séquence après la mise à niveau vers Xcode 5.1 et iOS 7.1

Lorsque je navigue entre les contrôleurs parent et enfant dans un contrôleur de navigation maître-détail, je vois une ombre sombre sur le côté droit de la barre de navigation en haut. Cela a commencé après la mise à niveau vers Xcode 5.1. Cela semble rude et distrayant. Comment puis-je m'en débarrasser?

84
Nihat
self.navigationController.navigationBar.translucent = NO; 

corrigé

50
Nihat
self.navigationController.view.backgroundColor = [UIColor whiteColor];

J'ai résolu ce problème en définissant la couleur d'arrière-plan de la vue du contrôleur de navigation.

134
nonamelive

la réponse de nonamelive est parfaite. Pour obtenir la même chose dans Interface Builder ET GARDER TOUJOURS LA TRADUCTION , sélectionnez le contrôleur de navigation et définissez un attribut d'exécution défini par l'utilisateur view.backgroundColor comme indiqué sur la capture d'écran (dans l'inspecteur d'identité). Répétez l'opération pour tous les contrôleurs de navigation qui présentent ce problème.

Il semble que tout ce problème se produise parce que la couleur noire (ou en fait, aucune couleur) de UINavigationController fuit au moment où CoreGraphics le capture au début de l'animation. Donc, le mettre en blanc évitera cela.

Identity Inspector -> User Defined Runtime Attributes

36
manmal

Cela semble être un bogue qui a été introduit dans iOS 7.1. Dans mon cas, cela est dû à une UIToolbar placée directement sous la barre de navigation. L'ombre foncée apparaît également dans la barre d'onglets translucide.

L'ombre semble provenir de la vue d'arrière-plan de la barre d'outils UIT. J'utilise maintenant cette solution de contournement dans le contrôleur de vue avec la barre d'outils qui masque la vue d'arrière-plan de la barre d'outils pendant la transition:

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    UIView *toolbarBackgroundView = [self.toolbar findViewRecursively:^BOOL(UIView *subview, BOOL *stop) {
        BOOL isToolbarBackgroundView = ([subview isKindOfClass:[UIImageView class]]
                                        && [NSStringFromClass(subview.class) isEqualToString:@"_UIToolbarBackground"]);
        if (isToolbarBackgroundView) {
            *stop = YES;
        }
        return (! isToolbarBackgroundView);
    }];
    if (toolbarBackgroundView) {
        // fade toolbar background view back in
        [UIView animateWithDuration:0.1f animations:^{
            toolbarBackgroundView.alpha = 1.0f;
        }];
    }
}

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];

    UIView *toolbarBackgroundView = [self.toolbar findViewRecursively:^BOOL(UIView *subview, BOOL *stop) {
        BOOL isToolbarBackgroundView = ([subview isKindOfClass:[UIImageView class]]
                                        && [NSStringFromClass(subview.class) isEqualToString:@"_UIToolbarBackground"]);
        if (isToolbarBackgroundView) {
            *stop = YES;
        }
        return (! isToolbarBackgroundView);
    }];
    if (toolbarBackgroundView) {
        // hide toolbar background view
        toolbarBackgroundView.alpha = 0.0f;
    }
}

Ceci est le code pour [UIView findViewRecursively:]

@interface UIView (FindSubview)

- (UIView*)findViewRecursively:(BOOL(^)(UIView* subview, BOOL* stop))recurse;

@end

@implementation UIView (FindSubview)

- (UIView*)findViewRecursively:(BOOL(^)(UIView* subview, BOOL* stop))recurse {
    for (UIView* subview in self.subviews) {
        BOOL stop = NO;
        if (recurse(subview, &stop)) {
            UIView* view = [subview findViewRecursively:recurse];
            if (view) return view;
        } else if (stop) {
            return subview;
        }
    }
    return nil;
}

@end

J'ai déposé ce radar: http://openradar.appspot.com/16418845

6
tom

Cela fonctionne pour moi dans Swift

Dans AppDelegate sur la méthode didFinishLaunchingWithOptions, j'ai défini ceci:

UIApplication.shared.windows.first?.backgroundColor = .white
4
pableiros

Cela semble se produire avec n'importe quelle barre (TabBar ou ToolBar) qui est translucide.
Donc, une façon de résoudre ce problème est de définir le _tabBar.translucent = NO; (dans mon cas). Cela empêche l'ombre indésirable sous la barre de navigation supérieure tout en laissant la barre de navigation translucide. Malheureusement, la barre inférieure n'est plus translucide.

Il peut être redéfini sur translucide mais tout cela doit se produire une fois l'animation de poussée complète terminée, ce qui fait que la commutation de cette propriété est bien visible.

Dans le cas, cependant, la barre inférieure doit également être translucide et je ne veux pas que l'utilisateur voit le changement, je l'ai résolu comme suit:

/*  create a simple quick animation of the bottom bar
    just before pushing the new controller */
[UIView animateWithDuration:0.1
                 animations:^{
                     _tabBar.barTintColor = [UIColor colorWithWhite:0.97254901960784 alpha:1.0]; // this is the closest color for my case
                     _tabBar.translucent = NO;
                 } completion:^(BOOL finished) {
                     /* now when the animation that makes the bar not translucent
                        is finished we can Push the new controller
                        the controller is instantiated before the animation code */
                     [self.navigationController pushViewController:controller animated:YES];
                 }];

Puis dans le viewDidAppear: Je reviens simplement sur ce point:

[UIView animateWithDuration:0.1
             animations:^{
                     _tabBar.barTintColor = nil;
                     _tabBar.translucent = YES;
                 }];

Il y a juste un petit changement dans l'apparence surtout mais c'est à peine perceptible et c'est bien mieux que d'avoir l'ombre sous la barre de navigation.

J'espère que cela aidera les autres à garder les barres translucides jusqu'à Apple corrige ce comportement car les barres SONT censées être cachées dans certains cas contrairement à ce qui a été suggéré dans d'autres articles en particulier pour le UITabBar

4
kacho
self.navigationController!.navigationBar.translucent = false;

Cela fonctionne pour moi, placez-le dans la fonction où vous poussez le nouveau ViewController

3
Shyam Raju

Ce qui suit fonctionne également et laisse la barre de navigation transparente:

[UIApplication sharedApplication].keyWindow.backgroundColor = [UIColor whiteColor];

3
seb

Voici ma variation ... elle nécessite beaucoup moins de code que la réponse de tom, et est plus efficace. C'est SI vous voulez une barre de navigation translucide et que vous souhaitez également résoudre ce problème d'ombre.

Dans le ViewController source (intégré au contrôleur de navigation) ...

- (void)viewDidAppear:(BOOL)animated
{
     self.navigationController.navigationBar.translucent = YES;
}

et

 - (void)viewWillDisappear:(BOOL)animated
 {
     self.navigationController.navigationBar.translucent = NO;
 }

Le résultat est le même que celui de Tom (visuellement, pour l'utilisateur final) et est plus facile à mettre en œuvre. J'espère que cela t'aides...

3
user2734823

Bien que ce ne soit pas la même que l'implémentation stock iOS, c'est une bonne façon de résoudre le problème:

- (void)viewWillAppear:(BOOL)animated {
    [UIView animateWithDuration:0.35f animations:^{
        self.tabBarController.tabBar.alpha = 1.0f;
    }];
}

- (void)viewWillDisappear:(BOOL)animated {
    [UIView animateWithDuration:0.35f animations:^{
        self.tabBarController.tabBar.alpha = 0.0f;
    }];
}

Vous obtiendrez une belle animation de fondu d'entrée/de sortie de la barre d'onglets. Ajoutez le code à la racine UIViewController.

1
Marko Nikolovski

Ou si vous utilisez le générateur d'interface, vous pouvez simplement sélectionner la barre de navigation de votre contrôleur de navigation et décochez la case Translucide entre le style et la teinte de la barre dans l'inspecteur d'attributs pour vous débarrasser de cet effet étrange -

Inspector

0
noob