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


91

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 dur et distrayant. Comment puis-je m'en débarrasser?

Réponses:


143
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.


Cette réponse est en fait très bonne. Pour une raison quelconque, Interface Builder ne vous permet pas d'accéder à la vue de votre contrôleur de navigation, mais il semble qu'une darkColorvue soit toujours présente et provoque ce problème.
superarts.org

1
C'est une excellente réponse car cela permet également à la barre de rester translucide tout en ne montrant pas la vilaine section noire qui saigne du contrôleur de navigation. Je souhaite juste qu'il y ait un moyen de le configurer dans le storyboard.
dimiguel

Exactement. De temps en temps, j'y pense et je suis un peu déçu par les autres réponses qui suggèrent de désactiver la transparence de la barre de navigation, car ils résolvent ce problème en désactivant une fonctionnalité, dont cette réponse indique le correctif réel. Dommage que ce comportement reste le même dans Xcode 7 / iOS 9.
superarts.org

1
Désolé, j'ai décliné cette réponse car l'arrière-plan de la fenêtre n'est pas la cause principale de ce problème. S'il vous plaît voir ma capture d'écran ci-jointe: imgur.com/a/SH5Dp Vous constaterez que le problème existe toujours, la teinte sombre vient d'être remplacée par une blanche, je suppose que les détails du contrôleur ont été `` coupés '' ou, d'une manière ou d'une autre, ne dessinez rien sous NavBar .
mariotaku

1
tabBarController? .view.backgroundColor = UIColor.white si le contrôleur racine est UITabBarController.
Vishal Singh

55
self.navigationController.navigationBar.translucent = NO; 

réparé


Où avez-vous placé cela?
Zorayr

Dans la méthode ViewDidLoad du contrôleur de vue maître
Nihat

Ajouter dans la vueDidAppear
Abdul Waheed

je pense que c'est en fait la bonne réponse. le navigationController.view.backgroundColor = .whitene fonctionne plus sur iOS 11.
AnBisw

1
@Annjawn, navigationController.view.backgroundColor = .whitefonctionne sur iOS 12. La suppression de translucide de la barre de navigation ne peut pas être utilisée lorsque cela est nécessaire, mais l'ombre noire ne l'est pas.
Alex Motor

38

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

Il semble que tout ce problème se produit parce que la couleur noire (ou en fait, aucune couleur) de UINavigationController fuit au moment où CoreGraphics prend des instantanés au début de l'animation. Donc, le régler sur blanc empêchera cela.

Inspecteur d'identité -> Attributs d'exécution définis par l'utilisateur


1
Je préfère cette approche, laissez Interface Builder UI le plus possible.
DazChong

iOS 8.4 n'a pas aidé
Maksim Kniazev

3
Fonctionne parfaitement avec Xcode 8.3.3. Juste pour souligner à nouveau, doit être UINavigationControlleractivé, pas sur le viewController.
jungledev

J'avais un navcon dans un tabcon et j'ai vu des ombres sur les deux barres (en haut et en bas) lors de l'utilisation de "Hides bottom bar on push" sur l'un des VC du navcon. Le réglage du fond blanc sur le navcon a corrigé les deux ombres. Merci!
nh32rg

6

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

L'ombre semble être causée par la vue d'arrière-plan de la UIToolbar. 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


2
Votre solution est bonne si vous ne voulez pas d'une barre de navigation translucide.
tom

Il existe un moyen plus simple d'obtenir le fichier backgroundView. [self.toolbar valueForKey:@"_backgroundView"]. Veuillez noter qu'il s'agit d'une API privée, mais je pense que vous ne serez pas attrapé par Apple car ce _backgroundViewn'est qu'un nom générique.
nonamelive

Cette réponse m'a informé de ce que je devais faire. Dans mon cas, c'était aussi simple que de décocher l'option translucide sur la UIToolbar dans le constructeur d'interface.
Greg W

4

Cela semble se produire avec n'importe quelle barre (TabBar ou ToolBar) 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 remis à translucide, mais tout cela doit se produire une fois que toute l'animation de poussée est terminée, donc la commutation de cette propriété est bien perceptible.

Au cas où, cependant, la barre inférieure doit également être translucide et je ne veux pas que l'utilisateur voie le changement, je l'ai résolu avec ce qui 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];
                 }];

Ensuite, dans le viewDidAppear:je retourne simplement cela:

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

Il y a juste un petit changement dans l'apparence en particulier, 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'à ce qu'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


J'ai pu résoudre ce problème en adoptant la solution de @ manmal: définissez l'attribut d'exécution view.backgroundColorde votre UITabBarController dans le storyboard et définissez-le sur une couleur blanche.
jamesk

4

Cela fonctionne pour moi dans Swift

Dans AppDelegatele didFinishLaunchingWithOptionsmode, je mets ceci:

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

4

Cela fonctionne pour moi sur iOS 13 avec des thèmes clairs et sombres ainsi que sur les anciennes versions d'iOS.

Ajoutez le code suivant à AppDelegate à la application(didFinishLaunchingWithOptions)méthode:

if #available(iOS 13.0, *) {
    window?.backgroundColor = UIColor.systemBackground
} else {
    window?.backgroundColor = UIColor.white
}

J'ai aussi essayé cette méthode, mais je rencontre un problème lors de la présentation d'un contrôleur de vue en mode par défaut. Ensuite, vous verrez le fond blanc de la fenêtre au lieu d'un noir. Cela a l'air bizarre. pouvez-vous s'il vous plaît suggérer une idée pour surmonter cette situation
varun v nair

3

Voici ma variante ... 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 voulez également résoudre ce problème d'ombre.

Dans le ViewController source (qui est 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 ce que fait Tom (visuellement, pour l'utilisateur final), et est plus facile à mettre en œuvre. J'espère que cela t'aides...


3
self.navigationController!.navigationBar.translucent = false;

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


Fou, mais parmi toutes les réponses, l'idée de le placer dans la fonction poussant au prochain VC était celle!
Coltuxumab

3

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

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


1

Bien que ce ne soit pas la même chose que l'implémentation iOS d'origine, c'est un bon moyen 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 entrant / sortant de la barre d'onglets. Ajoutez le code à la racine UIViewController.


-1

Ou si vous utilisez le générateur d'interface, vous pouvez simplement sélectionner la barre de navigation à partir de votre contrôleur de navigation et décocher 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 -

Inspecteur

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.