2010-05-14 21 views
61

¿Es posible agregar una UIView en la barra de tamaño de staus (320 x 20)? No quiero ocultar la barra de estado, solo quiero agregarla en la parte superior de la barra de estado.Agregar vista en StatusBar en iPhone

+4

Solo un comentario, en caso de que esté interesado en publicar en la tienda de aplicaciones de Apple, la [aplicación Reeder fue rechazada] (http://twitter.com/#!/ reederapp/status/125598161849942016) debido a esta característica. – phi

+1

@Irene: escribí una vista de barra de estado personalizada para mi aplicación [Python para iOS] (http://pythonforios.com) y la actualización fue aprobada recientemente para la tienda de aplicaciones. La política de Apple podría haber cambiado desde que la aplicación Reeder fue rechazada. – chown

+0

Muchas aplicaciones en Appstore con esta funcionalidad –

Respuesta

85

Usted puede lograr esto mediante la creación de su propia ventana por encima de la barra de estado existente.

Basta con crear una subclase sencilla de UIWindow con la siguiente anulación de initWithFrame:

@interface ACStatusBarOverlayWindow : UIWindow { 
} 
@end 

@implementation ACStatusBarOverlayWindow 
- (id)initWithFrame:(CGRect)frame { 
    if ((self = [super initWithFrame:frame])) { 
     // Place the window on the correct level and position 
     self.windowLevel = UIWindowLevelStatusBar+1.0f; 
     self.frame = [[UIApplication sharedApplication] statusBarFrame]; 

     // Create an image view with an image to make it look like a status bar. 
     UIImageView *backgroundImageView = [[UIImageView alloc] initWithFrame:self.frame]; 
     backgroundImageView.image = [UIImage imageNamed:@"statusBarBackground.png"]; 
     [self addSubview:backgroundImageView]; 
     [backgroundImageView release]; 

     // TODO: Insert subviews (labels, imageViews, etc...) 
    } 
    return self; 
} 
@end 

Ahora puede, por ejemplo en un controlador de vista de su aplicación, cree una instancia de la nueva clase y hacerlo visible.

overlayWindow = [[ACStatusBarOverlayWindow alloc] initWithFrame:CGRectZero]; 
overlayWindow.hidden = NO; 

estar al tanto de jugar con el estado de la clave ventana mediante el uso de - (void)makeKeyAndVisible o similar. Si usted hace su ventana principal (la UIWindow en su Delegado de aplicaciones) estado de la clave suelta, se encontrará con problemas de desplazamiento scrollviews arriba al tocar la barra de estado, etc.

+1

Tenga en cuenta que colocar una superposición sobre la barra de estado normal (la gris) y el negro opaco es simple. Si su aplicación tiene una barra translúcida, deberá ocultarla y colocar su propia vista en su lugar (ya que colocar una barra translúcida sobre la original solo hará un lío;)) – alleus

+0

Absolutamente brillante. –

+0

Es ese código que falta un "retorno de sí mismo"; al final de la función allí? –

3

Sólo para descartar el "No se puede hacer esto comentarios" ...

No sé cómo, pero sé que es factible. La aplicación de lector de Feed llamada Reeder hace eso.

Como puede ver en la captura de pantalla, Reeder coloca un pequeño punto en la parte superior derecha de la pantalla. Cuando lo tocas. La barra llenará toda la barra de estado hasta que vuelva a tocarla para hacerlo pequeña.

A small icon on the top right of the screenalt text

58

escribí una biblioteca estática mimicing Reeders superposición barra de estado, se puede encontrar aquí: https://github.com/myell0w/MTStatusBarOverlay

MTStatusBarOverlay MTStatusBarOverlay

Actualmente soporta iPhone y el iPad, estilos por defecto y la barra de estado negro opaco, rotación, 3 modos diferentes anymation, la historia de seguimiento y un montón de golosinas más!

¡Siéntase libre de utilizarlo o envíeme una Solicitud de extracción para mejorarlo!

+0

¡Brillante, gracias! – conorgriffin

+0

¿Cómo uso esto si no tengo una barra de estado en mi aplicación? –

+5

Malas noticias, Apple comenzó a rechazar aplicaciones usando MTStatusBarOverlay o soluciones similares que "muestran una superposición de barra de estado personalizada en la parte superior de la barra de estado nativa". Aparentemente viola HIG :( –

1

Antes que nada, muchas gracias a @Martin Alléus por proporcionar el código para esta implementación.

Acabo de publicar un problema que enfrenté y la solución que utilicé, ya que creo que otros pueden experimentar el mismo problema.

Si la aplicación se inicia mientras hay una llamada en curso, la altura de la barra de estado será de 40 píxeles y esto significa que la barra de estado personalizada se inicializará con esa altura. Pero si la llamada finaliza mientras todavía está en la aplicación, la altura de la barra de estado seguirá siendo de 40 píxeles y se verá raro.

Así que la solución es simple: He utilizado el centro de notificación para suscribirse a la barra de estado de cambio del marco delegado de la aplicación y ajustar el marco:

- (void)application:(UIApplication *)application didChangeStatusBarFrame:(CGRect)oldStatusBarFrame { 
    //an in call toggle was done  
    //fire notification 
    [[NSNotificationCenter defaultCenter] postNotificationName:kStatusBarChangedNotification object:[NSValue valueWithCGRect:oldStatusBarFrame]]; 
} 

Y en el ACStatusBarOverlayWindow que suscribirse a la notificación :

-(id)initWithFrame:(CGRect)frame 
{ 
    if ((self = [super initWithFrame:frame])) 
    { 
     // Place the window on the correct level & position 
     self.windowLevel = UIWindowLevelStatusBar + 1.0f; 
     self.frame = [UIApplication sharedApplication].statusBarFrame; 
     self.backgroundColor = [UIColor blackColor]; 

     //add notification observer for in call status bar toggling 
     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(statusBarChanged:) name:kStatusBarChangedNotification object:nil]; 
    } 
    return self; 
} 

y nuestro código para ajustar el marco:

- (void)statusBarChanged:(NSNotification*)notification { 
    //adjust frame...  
    self.frame = [UIApplication sharedApplication].statusBarFrame; 
    //you should adjust also the other controls you added here 
} 

El kStatusBarChangedNotification es solo una constante que he usado para facilitar la referencia, simplemente puede reemplazarlo con una cadena, o declarar la constante a nivel mundial.

4

Todas las respuestas se parece a trabajar, pero en iOS6.0 tengo problemas siguientes:

1/Rotaciones ve mal

2/ventana (barra de estado es una especie de ventana) necesaria RootViewController

Estoy usando la respuesta de myell0w, pero rotar no funciona bien. Acabo de eliminar una ventana extra y usar UIWindow desde AppDelegate para implementar la barra de estado. puede ser esta solución es aceptable sólo para una aplicación UIViewController ...

he implementado por la siguiente manera:

1/En ApplicationDelegate:

self.window.windowLevel = UIWindowLevelStatusBar + 1; 
self.window.backgroundColor = [UIColor clearColor]; 
self.window.rootViewController = _journalController; 

2/Crea UIView personalizada e implementar todo lo que necesita en el interior: para un ejemplo tangible de estado:

@interface LoadingStatusBar : UIControl 

y fácilmente crear y añadir a su contro Ver ller:

_loadingBar = [[LoadingStatusBar alloc] initWithFrame:topFrame]; 
[self addSubview:_loadingBar]; 

3/un poco de magia cuando añada su vista controlador (en initWithFrame :)

CGRect mainFrame = self.bounds; 
    mainFrame.origin.y = 20; 
    self.bounds = mainFrame; 

Su controlador de vista voluntad tiene 2 puntos de vista - vista de contenido y vista la barra de estado. Puede mostrar la barra de estado u ocultarla cuando lo desee. marco de vista del contenido será:

_contentView.frame = CGRectMake(0, 20, self.bounds.size.width, self.bounds.size.height); 

4/Y una última magia aquí :) Para detectar toques en el área no tangible que he usado:

-(id)hitTest:(CGPoint)point withEvent:(UIEvent *)event { 
    if (point.y < 20) return _loadingBar; 
    return [super hitTest:point withEvent:event]; 
} 

Por ahora funciona muy bien en iPad/iPhone y todos los iOS de 4 a 6.

Cuestiones relacionadas