iOS 7: la barra de estado se superpone a la vista

109

Tengo una ViewControllerque está dentro de una UINavigationcontroller, pero la barra de navegación está oculta. Cuando ejecuto la aplicación en iOS 7, la barra de estado se muestra en la parte superior de mi vista. Hay alguna manera de evitar esto?

No quiero escribir ningún código específico del sistema operativo.

Ingrese la descripción de la imagen aquí

Intenté fijar View controller-based status bar appearancea NO, pero no solucionar el problema.

aryaxt
fuente
He publicado mi respuesta para mostrar la barra de estado como iOS 6 en iOS 7 stackoverflow.com/questions/18294872/…
Desert Rose
2
También debe ajustar el origen y y el valor delta para manejar el problema de la barra de estado. Esto puede ayudarlo a stackoverflow.com/q/18980925/1545180
Ganapathy

Respuestas:

95

Xcode 5 tiene iOS 6/7 Deltasque está diseñado específicamente para resolver este problema. En el guión gráfico, moví mis vistas 20 píxeles hacia abajo para que se vean bien en iOS 7 y para que sea compatible con iOS 6, cambié Delta ya -20.

ingrese la descripción de la imagen aquí

Dado que mi guión gráfico no utiliza el diseño automático, para cambiar el tamaño de la altura de las vistas correctamente en iOS 6 tuve que configurar Delta heighttambién Delta Y.

aryaxt
fuente
8
su respuesta es correcta pero no funciona con la pantalla de 4 ". Actualice su respuesta si puede hacer que funcione también para la pantalla de 4". Gracias por adelantado.
2
@AnkitMehta No tuve que hacer nada específico para iphones de 4 "
aryaxt
5
trabajó para mi. Tenga en cuenta que para ver estos deltas, debe anular la selección de 'Usar diseño automático' en 'Identidad y tipo' para el guión gráfico.
marsant
2
Descubrí que además de establecer un -20 para ∆Y, también tenía que establecer un +20 para ∆Height
Toland Hon
3
¿Qué sucede cuando cambia la altura de la barra de estado? Por ejemplo: cuando el usuario activa el punto de acceso, etc .... entonces la altura es 40px ...
Lukasz
69

Si simplemente NO quiere ninguna barra de estado, necesita actualizar su plist con estos datos: Para hacer esto, en el plist, agregue esas 2 configuraciones:

<key>UIStatusBarHidden</key>
<true/>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>

En iOS 7, se espera que diseñe su aplicación con una barra de estado transparente superpuesta en mente. Vea la nueva aplicación meteorológica de iOS 7, por ejemplo.

Nathan H
fuente
3
En realidad, esta es la única buena respuesta, ya que soluciona el problema en su núcleo de la forma en que se suponía que debía hacerse. Entonces: ¡se necesitan votos a favor!
eleven59
5
Puede ser apropiado para algunas situaciones, pero debe tener mucho cuidado al ocultar la barra de estado. Solo para vistas que son justificadamente a pantalla completa, como reproductores multimedia o visores de imágenes.
smileBot
1
@ eleven59, te refieres a la forma en que los autócratas de Apple pretenden.
JohnK
1
Definitivamente me gusta esto mejor que cambiar el desplazamiento de un controlador de vista (que se siente realmente sucio).
Benjamin Oman
ocultar la barra de estado no es una buena idea ... Sé que esta es la forma más fácil de manejar iOS 7, pero NECESITA tiempo ...
Fahim Parkar
43

Este es el comportamiento predeterminado para UIViewControlleriOS 7. La vista será de pantalla completa, lo que significa que la barra de estado cubrirá la parte superior de la vista.

Si tiene un UIViewControllerdentro de a UINavigationControllery la barra de navegación es visible, puede tener el siguiente código en su viewDidLoado tener una imagen de fondo para que la barra de navegación haga el truco.

self.edgesForExtendedLayout = UIRectEdgeNone;

Si tiene la barra de navegación oculta, entonces debe ajustar todos los elementos de UIView cambiando 20 puntos. No veo ninguna otra solución. Usar diseño automático ayudará un poco.

Aquí está el código de muestra para detectar la versión de iOS, si desea compatibilidad con versiones anteriores.

NSUInteger DeviceSystemMajorVersion() {
    static NSUInteger _deviceSystemMajorVersion = -1;
    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{
        NSString *systemVersion = [UIDevice currentDevice].systemVersion;
        _deviceSystemMajorVersion = [[systemVersion componentsSeparatedByString:@"."][0] intValue];
    });

   return _deviceSystemMajorVersion;
}
Vincent
fuente
18
En lugar de buscar, analizar y comparar la versión del sistema, se recomienda utilizarif ([self respondsToSelector:@selector(edgesForExtendedLayout)])
Sebastian Hojas
15

La única solución de trabajo que he hecho yo mismo.

Aquí está mi subclase UIViewController https://github.com/comonitos/ios7_overlaping

1 subclase de UIViewController

2 Subclase su window.rootViewController de esa clase.

3 ¡Voila!

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

    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
        CGRect screen = [[UIScreen mainScreen] bounds];
        if (self.navigationController) {
            CGRect frame = self.navigationController.view.frame;
            frame.origin.y = 20;
            frame.size.height = screen.size.height - 20;
            self.navigationController.view.frame = frame;
        } else {
            if ([self respondsToSelector: @selector(containerView)]) {
                UIView *containerView = (UIView *)[self performSelector: @selector(containerView)];

                CGRect frame = containerView.frame;
                frame.origin.y = 20;
                frame.size.height = screen.size.height - 20;
                containerView.frame = frame;
            } else {
                CGRect frame = self.view.frame;
                frame.origin.y = 20;
                frame.size.height = screen.size.height - 20;
                self.view.frame = frame;
            }
        }
    }
}

4 Agregue esto para que su barra de estado sea blanca Justo después de [self.window makeKeyAndVisible]; !!!

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
}
comonitos
fuente
pero esto no muestra el tiempo en la parte superior ... Mayor desventaja ... :(
Fahim Parkar
Funciona muy bien, pero para el paso 4 debe usar favoriteStatusBarStyle en su controlador de vista, ya que setStatusBarStyle está obsoleto y su acción predeterminada es no hacer nada. stackoverflow.com/a/19014724/1192732
CpnCrunch
13
-(UIStatusBarStyle)preferredStatusBarStyle
{
    return UIStatusBarStyleLightContent;
}

-(void)viewWillLayoutSubviews{

 if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) 
  {
    self.view.clipsToBounds = YES;
    CGRect screenRect = [[UIScreen mainScreen] bounds];
    CGFloat screenHeight = 0.0;
    if(UIDeviceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation]))
        screenHeight = screenRect.size.height;
    else
        screenHeight = screenRect.size.width;
    CGRect screenFrame = CGRectMake(0, 20, self.view.frame.size.width,screenHeight-20);
    CGRect viewFrame1 = [self.view convertRect:self.view.frame toView:nil];
    if (!CGRectEqualToRect(screenFrame, viewFrame1))
    {
        self.view.frame = screenFrame;
        self.view.bounds = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
    }
  }
}

Agregar clave en plist --- Ver la apariencia de la barra de estado basada en el controlador: NO

Darshit Shah
fuente
cambie el color de la ventana si es necesario
Darshit Shah
Gracias, resolvió mi problema de superposición. Pero todavía hay un problema: ver la apariencia de la barra de estado basada en el controlador: NO es para ocultar la barra de estado, supongo. Pero cuando lo configuro en SÍ, entonces no muestra la barra de estado y cuando lo configuro en NO, entonces muestra la barra de estado. Entonces, por favor dime, ¿estoy equivocado con el concepto o qué?
Nayan
1
Creo que porque toma el color semitransparente predeterminado establecido en didFinishLaunchingWithOptions 'self.window.backgroundColor = [UIColor blueColor];' y establecer en plist Ver la apariencia de la barra de estado basada en el controlador SÍ
Darshit Shah
¡Genial gracias! Además, solo para señalar que los documentos de Apple recomiendan verificar con if (NSFoundationVersionNumber <= NSFoundationVersionNumber_iOS_6_1) {} else {}. ¡Salud!
Joel Balmer
Muchas gracias. Su código es muy útil para nosotros. Por favor, debe explicar acerca de la función viewWillLayoutSubviews.
user3182143
4

Para ocultar la barra de estado en ios7, siga estos sencillos pasos:

En Xcode, vaya a la Resourcescarpeta " " y abra " (app name)-Info.plist file".

  • busque la View controller based status bar appearanceclave " " y establezca su valor " NO"
  • busque la Status bar is initially hiddenclave " " y establezca su valor " YES"

Si las claves no están allí, puede agregarlas seleccionando " information property list" en la parte superior y haciendo clic en el icono +

Mandeep Pasbola
fuente
Lea la pregunta con claridad, no pidió ocultar totalmente la barra de estado.
ShayanK
1
@AspersionCast: Preguntó "¿Hay alguna forma de evitar esto?" y esta es una de las formas de evitarlo.
Mandeep Pasbola
3

Si usa xibs, una implementación muy fácil es encapsular todas las subvistas dentro de una vista de contenedor con indicadores de cambio de tamaño (que ya usará para compatibilidad de 3.5 "y 4") para que la jerarquía de vista se vea así

jerarquía xib

y luego viewDidLoad, haz algo como esto:

- (void)viewDidLoad
{
  [super viewDidLoad];
  // initializations
  if(SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) // only for iOS 7 and above
  {
    CGRect frame = containerView.frame;
    frame.origin.y += 20;
    frame.size.height -= 20;
    containerView.frame = frame;
  }
}

De esta forma, no es necesario modificar las puntas para la compatibilidad con iOS 7. Si tiene un fondo, puede mantenerlo afuera containerViewy dejar que cubra toda la pantalla.

tipycalFlow
fuente
3

Esto es todo lo que se necesita para eliminar la barra de estado. ingrese la descripción de la imagen aquí

Tony
fuente
2

Para la barra de navegación:

Escribiendo este código:

self.navigationController.navigationBar.translucent = NO;

me acaba de hacer el truco.

Saru
fuente
1

La respuesta de Vincent edgeForExtendedLayout funcionó para mí.

Estas macros ayudan a determinar la versión del sistema operativo, lo que facilita

// 7.0 and above 
#define IS_DEVICE_RUNNING_IOS_7_AND_ABOVE() ([[[UIDevice currentDevice] systemVersion] compare:@"7.0" options:NSNumericSearch] != NSOrderedAscending) 

// 6.0, 6.0.x, 6.1, 6.1.x
#define IS_DEVICE_RUNNING_IOS_6_OR_BELOW() ([[[UIDevice currentDevice] systemVersion] compare:@"6.2" options:NSNumericSearch] != NSOrderedDescending) 

agregue estas macros al archivo prefix.pch de su proyecto y se puede acceder a ellas desde cualquier lugar

if(IS_DEVICE_RUNNING_IOS_7_AND_ABOVE())
{
 //some iOS 7 stuff
 self.edgesForExtendedLayout = UIRectEdgeNone;
}

if(IS_DEVICE_RUNNING_IOS_6_OR_BELOW())
{
 // some old iOS stuff
}
RamaKrishna Chunduri
fuente
1
para mí self.edgesForExtendedLayout = UIRectEdgeNone; no funciona ... ¿por qué?
Fahim Parkar
1

He publicado mi respuesta a otra publicación con la misma pregunta con esta.

De la Guía de transición de Apple iOS7, https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/TransitionGuide/AppearanceCustomization.html#//apple_ref/doc/uid/TP40013174-CH15-SW1

Específicamente automaticallyAdjustsScrollViewInsets=YESy set self.edgesForExtendedLayout = UIRectEdgeNonefunciona para mí cuando no quiero que se superpongan y tengo un archivo tableviewcontroller.

Liangjun
fuente
0

Si desea que se habilite "Usar diseño automático" a cualquier costo, coloque el siguiente código en viewdidload.

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) 
{
        self.edgesForExtendedLayout = UIRectEdgeNone;
        self.extendedLayoutIncludesOpaqueBars = NO;
        self.automaticallyAdjustsScrollViewInsets = NO;
}
Ali Shahid
fuente
0

Mi barra de estado y mi barra de navegación se superponen después de regresar de la vista horizontal de YTPlayer. Aquí está mi solución después de probar la versión de @comonitos pero no funciona en mi iOS 8

- (void)fixNavigationBarPosition {
    if (self.navigationController) {
        CGRect frame = self.navigationController.navigationBar.frame;
        if (frame.origin.y != 20.f) {
            frame.origin.y = 20.f;
            self.navigationController.navigationBar.frame = frame;
        }
    }
}

Simplemente llame a esta función siempre que desee fijar la posición de la barra de navegación. Llamé a YTPlayerViewDelegate'splayerView:didChangeToState:

- (void)playerView:(YTPlayerView *)playerView didChangeToState:(YTPlayerState)state {
    switch (state) {
        case kYTPlayerStatePaused:
        case kYTPlayerStateEnded:
            [self fixNavigationBarPosition];
            break;
        default:
    }
}
John Pang
fuente