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?

Nihat
fuente

Respuestas:

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

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

no meloso
fuente
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

Nihat
fuente
¿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

manmal
fuente
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

tom
fuente
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

kacho
fuente
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
pableiros
fuente
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
}
petrsyn
fuente
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...

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

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

Shyam Raju
fuente
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];

seb
fuente
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.

Nikolovski
fuente
-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

novato
fuente