iOS 7 y posterior: configure el estilo de la barra de estado por controlador de vista

79


Intenté muchas formas de configurar el estilo de la barra de estado (predeterminado o contenido ligero) pero no puedo hacer que funcione por controlador de vista. Puedo configurar el estilo de la barra de estado solo para toda la aplicación.

¿Alguien tiene una pista?

Lo intenté UIViewControllerBasedStatusBarAppearance

y

-(UIStatusBarStyle)preferredStatusBarStyle{ 
    return UIStatusBarStyleLightContent; 
}

pero estos métodos no funcionan.

Van Du Tran
fuente
1
Y asegúrese de que la barra de navegación no se superponga con la barra de estado ....
Rajneesh071
Usé un pequeño truco para ello (y para controlar el estado visible / oculto): decidí publicarlo como pod 'UIViewController + ODStatusBar' ( cocoapods.org/pods/UIViewController+ODStatusBar )
Alex Nazarsky
1
Esta es solo una de las docenas de API en las que Apple cambia aleatoriamente el comportamiento de una versión de iOS a la siguiente y, por alguna razón, no ha habido una revuelta completa de desarrolladores. Tendrá que modificar su implementación para que se ajuste a la versión de iOS en la que se ejecuta su aplicación y probarla cada vez que cree una versión más nueva.
Bron Davies

Respuestas:

139

¿Has probado esto?

  1. Establezca "Ver apariencia de la barra de estado basada en el controlador" ( UIViewControllerBasedStatusBarAppearance) YESen su Info.plist. ( YESes el valor predeterminado, por lo que también puede dejar este valor fuera de su plist).

  2. En su método viewDidLoad, llame [self setNeedsStatusBarAppearanceUpdate].

  3. Implementar preferredStatusBarStyle, devolviendo el estilo de barra de estado que desea para este controlador de vista.

    - (UIStatusBarStyle) preferredStatusBarStyle { 
        return UIStatusBarStyleLightContent; 
    }
    
Greg
fuente
Aunque no necesitaba el paso 1
Van Du Tran
2
Este trabajo no funciona para Iphone 5 + ios7. UIViewControllerBasedStatusBarAppearance es NO y [[UIApplication sharedApplication] setStatusBarStyle: UIStatusBarStyleBlackTranslucent]; funciona bien para mi caso :)
Femina
4
@vishal funciona con aplicaciones basadas en UINavigationController si pones ese código en tu subclase personalizada de UINavigationController
anneblue
3
No necesita el segundo paso.
pronebird
4
No me funciona en iOS 8. Esto solo cambia el valor predeterminado. Lo que necesitaba para ser blanco, ahora pasa al predeterminado.
noobsmcgoobs
74

Hay un problema aquí si su controlador de vista está dentro de UINavigationController independiente y no es parte de UINavigationController basado en Storyboard, entonces todos los métodos fallan. Me encontré con esta situación y luego, para configurar la barra de estado en el estilo de luz, usé lo siguiente

[self.navigationController.navigationBar setBarStyle:UIBarStyleBlack];

Esto funcionó perfectamente para mí.

vishal dharankar
fuente
7
No funciona si la barra de navegación de su controlador de navegación está oculta.
MLQ
Un consejo similar se aplica a un UISplitViewController. Terminé subclasificando.
Stephen Darlington
1
Según tengo entendido, UINavigationBar.barStyleanula preferredStatusBarStyle. No importa cómo lo establezca preferredStatusBarStyle, un maldito 'UINavigationBar.setBarStyle' se hace cargo de todo.
Desmond DAI
22

EDITAR: Esta solución está obsoleta en iOS 9. Elija una de las otras respuestas.

Con UIViewControllerBasedStatusBarAppearanceestablecido en NO, pude establecer el estilo en texto blanco usando:

[UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleBlackTranslucent;

Esto se debe a que el color del texto de este estilo era blanco en iOS 6 y versiones anteriores.

ACTUALIZACIÓN: Según @jowie, puedes probar eso en iOS8:

[UIApplication sharedApplication].statusBarStyle = UIBarStyleBlack;
caulitomaz
fuente
¿Leíste la pregunta con atención? Está pidiendo una solución iOS7 y también su estilo claro, no oscuro, que es en tu caso.
vishal dharankar
Funciona en iOS7. Lo leí con atención. Y sobre UIBarStyleBlackTranslucent, funciona porque este estilo en iOS6 tenía un fondo negro (translúcido) con texto blanco. Cuando haces eso en iOS7, solo muestra el texto en blanco. Sé que parece hackear, pero fue la única forma en que descubrí para controlar realmente la barra.
caulitomaz
Para iOS 8, use UIBarStyleBlack.
jowie
Gracias @MatthieuRiegler, pondré un aviso.
caulitomaz
14

En Swift pude hacer esto escribiendo:

let tbc : UITabBarController = self.window?.rootViewController as UITabBarController
var moreViewController : UINavigationController = tbc.moreNavigationController

moreViewController.navigationBar.barStyle = UIBarStyle.Black

Básicamente estás interesado en la última línea.
Esto resultó en que la barra de pestañas cambiara a blanco:

ingrese la descripción de la imagen aquí

Tenga en cuenta que no cambié nada Info.plistpara lograr este resultado.
Para obtener más información sobre el cambio Navigation Status Bar, consulte este enlace: http://www.appcoda.com/customize-navigation-status-bar-ios-7/

Fengson
fuente
Esto funciona. Sin embargo, no utiliza el nuevo "UIStatusBarStyleLightContent", me pregunto si es una solución a prueba de futuro. ¡Aún resuelve el problema!
Van Du Tran
1
Hubiera sido una gran respuesta, pero no funciona si la barra de navegación está oculta.
MLQ
13

En el método viewDidLoad, ponga esto:

C objetivo

[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
[self setNeedsStatusBarAppearanceUpdate];

Rápido

UIApplication.shared.statusBarStyle = .lightContent
self.setNeedsStatusBarAppearanceUpdate()
Jota Freitas Jr
fuente
Me complace ayudarlo Gagan
Jota Freitas Jr
Parece extraño que el controlador de vista esté actualizando una propiedad para toda la aplicación; la solución debería ser para toda la aplicación (que vive en AppDelegate) o por controlador de vista.
Zorayr
equivalente rápido de este método UIApplication.sharedApplication (). setStatusBarStyle (UIStatusBarStyle.LightContent, animado: falso)
minhazur
Para que esto funcione, la apariencia de la barra de estado basada en el controlador de vista debe establecerse en NO en las propiedades de destino. Creo que este es el mejor método porque es simple y obvio.
n13
7

Apuesto a que tiene su controlador de vista integrado en un controlador de navegación. Para evitar configurar el estilo de la barra de navegación para .Blackusar esta subclase:

class YourNavigationController: UINavigationController {
    override func childViewControllerForStatusBarStyle() -> UIViewController? {
        return topViewController
    }
}
SoftDesigner
fuente
5

Rápido:

let tbc : UITabBarController = self.window?.rootViewController as UITabBarController
var moreViewController : UINavigationController = tbc.moreNavigationController
moreViewController.navigationBar.barStyle = UIBarStyle.Black

C objetivo:

agregue esto al controller.mmétodo de archivo viewDidLoad:

[self setNeedsStatusBarAppearanceUpdate].

luego implemente este método en ese mismo controller.marchivo:

- (UIStatusBarStyle) preferredStatusBarStyle { 
    return UIStatusBarStyleLightContent; 
}

Documentos oficiales:

https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/TransitionGuide/Bars.html

Artículo que escribí en mi blog:

http://www.ryadel.com/2015/03/04/xcode-set-status-bar-style-and-color-in-objective-c/

Darkseal
fuente
1

En el ViewController que desea cambiar el color de la barra de estado

- (void) viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];
}

- (void) viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
}
jxdwinter
fuente
0

Extensión rápida para esto porque siempre olvido cómo funciona esto

extension UIViewController {
    // utility to set the status bar appearance
    // Note: Make sure "View controller-based status bar appearance" is set to NO in your target settings or this won't work
    func setStatusBarForDarkBackground(dark: Bool) {
        UIApplication.sharedApplication().statusBarStyle = dark ? .LightContent : .Default
        setNeedsStatusBarAppearanceUpdate()
    }
}
n13
fuente
0

Xcode 10.3,

En iPhone 8 12.4 Simulator, está bien.

En iPhone X 12.4 Simulator, probé todo lo anterior, no está bien.

Luego lo agrego a mano, la barra de estado consta de tiempo, batería, celular.

11

StatusBarView


class StatusBottomView: UIView {
    private var batteryView:BatteryView!
    private var timeLabel:UILabel!
    private var timer:Timer?

    override init(frame: CGRect) {
        super.init(frame: frame)
        addSubviews()
    }

    private func addSubviews() {
        batteryView = BatteryView()
        batteryView.tintColor = UIColor.blue
        addSubview(batteryView)
        timeLabel = UILabel()
        timeLabel.textAlignment = .center
        timeLabel.font = UIFont.systemFont(ofSize: 12)
        timeLabel.textColor = UIColor.blue
        addSubview(timeLabel)
        didChangeTime()
        addTimer()
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        let h = frame.size.height
        let x: CGFloat = 80
        batteryView.frame.origin = CGPoint(x: ScreenHeight - x - DZMBatterySize.width, y: (h - DZMBatterySize.height) / 2)
        timeLabel.frame = CGRect(x: x, y: 0, width: 50, height: h)
    }

    // MARK: -- Timer

    func addTimer() {
        if timer == nil {
            timer = Timer.scheduledTimer(timeInterval: 15, target: self, selector: #selector(didChangeTime), userInfo: nil, repeats: true)
            RunLoop.current.add(timer!, forMode: .common)
        }
    }


    func removeTimer() {
        if timer != nil {
            timer!.invalidate()
            timer = nil
        }
    }


    @objc func didChangeTime() {
        timeLabel.text = TimerString("HH:mm")
        batteryView.batteryLevel = UIDevice.current.batteryLevel
    }

}

BatteryLevelView

class BatteryView: UIImageView {

    override var tintColor: UIColor! {

        didSet{ batteryLevelView.backgroundColor = tintColor }
    }

    /// BatteryLevel
    var batteryLevel:Float = 0 {

        didSet{ setNeedsLayout() }
    }

    /// BatteryLevelView
    private var batteryLevelView:UIView!

    convenience init() {

        self.init(frame: CGRect(x: 0, y: 0, width: DZMBatterySize.width, height: DZMBatterySize.height))
    }


    override init(frame: CGRect) {

        super.init(frame: CGRect(x: 0, y: 0, width: DZMBatterySize.width, height: DZMBatterySize.height))

        addSubviews()
    }

    func addSubviews() {

        batteryLevelView = UIView()
        batteryLevelView.layer.masksToBounds = true
        addSubview(batteryLevelView)

        image = UIImage(named: "battery_black")?.withRenderingMode(.alwaysTemplate)
        tintColor = UIColor.white
    }

    override func layoutSubviews() {
        super.layoutSubviews()

        let spaceW:CGFloat = 1 * (frame.width / DZMBatterySize.width) * HJBatteryLevelViewScale
        let spaceH:CGFloat = 1 * (frame.height / DZMBatterySize.height) * HJBatteryLevelViewScale

        let batteryLevelViewY:CGFloat = 2.1*spaceH
        let batteryLevelViewX:CGFloat = 1.4*spaceW
        let batteryLevelViewH:CGFloat = frame.height - 3.4*spaceH
        let batteryLevelViewW:CGFloat = frame.width * HJBatteryLevelViewScale
        let batteryLevelViewWScale:CGFloat = batteryLevelViewW / 100

        var tempBatteryLevel = batteryLevel

        if batteryLevel < 0 {

            tempBatteryLevel = 0

        }else if batteryLevel > 1 {

            tempBatteryLevel = 1

        }

        batteryLevelView.frame = CGRect(x: batteryLevelViewX , y: batteryLevelViewY, width: CGFloat(tempBatteryLevel * 100) * batteryLevelViewWScale, height: batteryLevelViewH)
        batteryLevelView.layer.cornerRadius = batteryLevelViewH * 0.125
    }

}


dengApro
fuente