Sombra oscura en la barra de navegación durante la transición de segue después de actualizar a Xcode 5.1 e iOS 7.1


91

Cuando estoy navegando de un lado a otro entre los controladores principal y secundario en un controlador de navegación de detalle principal, veo una sombra oscura en el lado derecho de la barra de navegación en la parte superior. Comenzó después de que actualicé a Xcode 5.1. Se siente áspero y molesto. ¿Cómo puedo deshacerme de él?

Respuestas:


144
self.navigationController.view.backgroundColor = [UIColor whiteColor];

Resolví este problema configurando el color de fondo de la vista del controlador de navegación.


Esta respuesta es realmente muy buena. Por alguna razón, Interface Builder no le permite acceder a la vista de su controlador de navegación, pero parece que una darkColorvista todavía está allí y causa este problema.
superarts.org

1
Esta es una gran respuesta porque también permite que la barra permanezca translúcida sin mostrar la fea sección negra que sangra desde el controlador de navegación. Solo desearía que hubiera una forma de configurarlo en el guión gráfico.
dimiguel

Exactamente. De vez en cuando lo pienso y me decepciono un poco por las otras respuestas que sugieren desactivar la transparencia de la barra de navegación, ya que básicamente están resolviendo este problema desactivando una función, que esta respuesta señala la solución real. Lástima que este comportamiento siga siendo el mismo en Xcode 7 / iOS 9.
superarts.org

1
Lo siento, voté en contra de esta respuesta porque el fondo de la ventana no es la causa principal de este problema. Por favor, vea mi captura de pantalla adjunta: imgur.com/a/SH5Dp Encontrará que el problema aún existe, la sombra oscura acaba de ser reemplazada por una blanca, supongo que el controlador de detalles se 'recortó' o de alguna manera, hace que no dibuje nada debajo de NavBar .
mariotaku

1
tabBarController? .view.backgroundColor = UIColor.white en caso de que el controlador raíz sea UITabBarController.
Vishal Singh

55
self.navigationController.navigationBar.translucent = NO; 

arreglado


¿Dónde colocaste esto?
Zorayr

En el método ViewDidLoad del controlador de vista maestro
Nihat

agregar en viewDidAppear
Abdul Waheed

Creo que esta es la respuesta correcta. el navigationController.view.backgroundColor = .whiteya no funciona en iOS 11.
AnBisw

1
@Annjawn, navigationController.view.backgroundColor = .whitefunciona en iOS 12. La eliminación de translúcido de la barra de navegación no se puede usar en situaciones en las que es necesario, pero la sombra negra no.
Alex Motor

38

La respuesta de nonamelive es perfecta. Para lograr lo mismo en Interface Builder Y MANTENER LA TRANSLUCENCIA , seleccione el controlador de navegación y establezca un atributo de tiempo de ejecución definido por el usuario view.backgroundColorcomo se muestra en la captura de pantalla (en el Inspector de identidad). Repita para todos los controladores de navegación que muestren este problema.

Parece que todo este problema ocurre porque el color negro (o en realidad, no hay color) de UINavigationController se está filtrando en el momento en que CoreGraphics lo captura al comenzar la animación. Por lo tanto, configurarlo en blanco evitará eso.

Inspector de identidad -> Atributos de tiempo de ejecución definidos por el usuario


1
Prefiero este enfoque, dejar que la interfaz de usuario de Interface Builder se rellene tanto como sea posible.
DazChong

iOS 8.4 no ayudó
Maksim Kniazev

3
Funciona perfectamente con Xcode 8.3.3. Solo para volver a enfatizar, debe estar activado UINavigationController, no en viewController.
jungledev

Tenía un navcon en un tabcon y vi sombras en ambas barras (superior e inferior) cuando usaba "Oculta la barra inferior al empujar" en uno de los VC del navcon. Establecer el fondo blanco en el navcon corrigió ambas sombras. ¡Gracias!
nh32rg

6

Este parece ser un error que se introdujo en iOS 7.1. En mi caso, es causado por una UIToolbar colocada directamente debajo de la barra de navegación. La sombra oscura también aparece en la barra de pestañas translúcida.

La sombra parece estar causada por la vista de fondo de UIToolbar. Ahora uso esta solución en el controlador de vista con la barra de herramientas que oculta la vista de fondo de la barra de herramientas durante la transición:

- (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;
    }
}

Este es el código para [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

Presenté este radar: http://openradar.appspot.com/16418845


2
Su solución está bien si no desea una barra de navegación translúcida.
Tom

Hay una forma más fácil de obtener el backgroundView. [self.toolbar valueForKey:@"_backgroundView"]. Tenga en cuenta que esta es una API privada, pero creo que Apple no lo detectará porque _backgroundViewes solo un nombre genérico.
finaliza el

Esta respuesta me indicó lo que tenía que hacer. En mi caso, fue tan simple como desmarcar la opción translúcida en UIToolbar en el generador de interfaces.
Greg W

4

Parece suceder con cualquier barra (TabBar o ToolBar) que sea translúcida.
Entonces, una forma de solucionarlo es configurar el _tabBar.translucent = NO;(en mi caso). Esto evita la sombra no deseada debajo de la barra de navegación superior mientras deja la barra de navegación translúcida. Desafortunadamente, la barra inferior ya no es translúcida.

Puede volver a ser translúcido, pero todo esto tiene que suceder después de que finalice toda la animación de empuje, por lo que el cambio de esta propiedad es bien notable.

Sin embargo, en caso de que la barra inferior también tenga que ser translúcida y no quiero que el usuario vea el cambio, lo resolví con lo siguiente:

/*  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];
                 }];

Luego, en el viewDidAppear:I simplemente revierte eso:

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

Hay solo un pequeño cambio en la apariencia, especialmente, pero apenas se nota y es mucho mejor que tener la sombra debajo de la barra de navegación.

Espero que ayude a otros a mantener las barras translúcidas hasta que Apple corrija este comportamiento, ya que las barras ESTÁN destinadas a estar ocultas en algunos casos, a diferencia de lo que se sugirió en otras publicaciones, especialmente para UITabBar


Pude solucionar este problema adoptando la solución de @manmal: defina el atributo de tiempo de ejecución view.backgroundColorpara su UITabBarController en el guión gráfico y configúrelo en un color blanco.
jamesk

4

Esto me funciona en Swift

En AppDelegateel didFinishLaunchingWithOptionsmétodo, configuro esto:

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

4

Esto me funciona en iOS 13 con temas claros y oscuros y también en versiones anteriores de iOS.

Agregue el siguiente código a AppDelegate al application(didFinishLaunchingWithOptions)método:

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

Yo también probé este método, pero tengo un problema al presentar un controlador de vista en el modo predeterminado. Entonces verá el fondo blanco de la ventana en lugar de negro. Eso se ve raro. ¿Puede sugerir alguna idea para superar esta situación?
varun v nair

3

Aquí está mi variación ... requiere mucho menos código que la respuesta de Tom y es más eficiente. Esto es SI desea una barra de navegación translúcida y también desea solucionar ese problema de sombra.

En el ViewController de origen (que está incrustado en el controlador de navegación) ...

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

y

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

El resultado es el mismo que hace Tom (visualmente, para el usuario final) y es más fácil de implementar. Espero que esto ayude...


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

Esto funciona para mí, colóquelo dentro de la función donde empuja el nuevo ViewController


Loco, pero entre todas las respuestas, ¡la idea de colocarlo en la función empujando al siguiente VC fue la indicada!
Coltuxumab

3

Lo siguiente también funciona y deja transparente la barra de navegación:

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


1

Si bien no es lo mismo que la implementación estándar de iOS, esta es una buena manera de solucionar el problema:

- (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;
    }];
}

Obtendrá una bonita animación de aparición / desaparición gradual de la barra de pestañas. Agrega el código en la raíz UIViewController.


-1

O si está utilizando el generador de interfaces, puede seleccionar la barra de navegación desde su controlador de navegación y desmarcar la casilla de verificación Translúcida entre Estilo y Tinte de barra en el Inspector de atributos para deshacerse de ese efecto extraño:

Inspector

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.