iOS 7 und höher: Legen Sie den Stil der Statusleiste pro Ansichts-Controller fest

79


Ich habe viele Möglichkeiten ausprobiert, um den Statusleistenstil festzulegen (Standard oder Lichtinhalt), kann ihn jedoch nicht auf Basis eines View-Controllers zum Laufen bringen. Ich kann den Statusleistenstil nur für die gesamte App festlegen.

Hat jemand einen Hinweis?

Ich habe es versucht UIViewControllerBasedStatusBarAppearance

und

-(UIStatusBarStyle)preferredStatusBarStyle{ 
    return UIStatusBarStyleLightContent; 
}

Diese Methoden funktionieren jedoch nicht.

Van Du Tran
quelle
1
Und stellen Sie sicher, dass die Navigationsleiste nicht mit der Statusleiste überlappt wird ....
Rajneesh071
Ich habe einen kleinen Trick dafür verwendet (und um den sichtbaren / verborgenen Zustand zu steuern) - ich habe beschlossen, ihn als Pod 'UIViewController + ODStatusBar' ( cocoapods.org/pods/UIViewController+ODStatusBar ) zu veröffentlichen
Alex Nazarsky
1
Dies ist nur eine von Dutzenden von APIs, bei denen Apple das Verhalten von einer iOS-Version zur nächsten zufällig ändert, und aus irgendeinem Grund gab es keine vollständige Entwicklerrevolte. Sie müssen Ihre Implementierung an die Version von iOS anpassen, auf der Ihre App ausgeführt wird, und sie jedes Mal testen, wenn Sie für eine neuere Version erstellen.
Bron Davies

Antworten:

140

Hast du das versucht?

  1. Setzen Sie in Ihrer Info.plist auf "Controller-basiertes Erscheinungsbild der Statusleiste anzeigen " ( UIViewControllerBasedStatusBarAppearance) YES. ( YESist die Standardeinstellung, daher können Sie diesen Wert auch einfach aus Ihrer Liste streichen.)

  2. Rufen Sie in Ihrer viewDidLoad-Methode auf [self setNeedsStatusBarAppearanceUpdate].

  3. Implementieren Sie preferredStatusBarStyleund geben Sie den gewünschten Statusleistenstil für diesen Ansichtscontroller zurück.

    - (UIStatusBarStyle) preferredStatusBarStyle { 
        return UIStatusBarStyleLightContent; 
    }
    
Greg
quelle
Ich brauchte Schritt 1 nicht
Van Du Tran
2
Dies funktioniert nicht für Iphone 5 + ios7. UIViewControllerBasedStatusBarAppearance ist NO und [[UIApplication sharedApplication] setStatusBarStyle: UIStatusBarStyleBlackTranslucent]; funktioniert gut für meinen Fall :)
Femina
4
@vishal funktioniert mit UINavigationController-basierten Apps, wenn Sie diesen Code in Ihre benutzerdefinierte UINavigationController-Unterklasse
einfügen
3
Sie brauchen keinen 2. Schritt.
Pronebird
4
Funktioniert bei iOS 8 nicht. Dies ändert nur die Standardeinstellung. Was ich weiß sein musste, geht jetzt auf die Standardeinstellung.
Noobsmcgoobs
74

Wenn sich Ihr View Controller in einem eigenständigen UINavigationController befindet und nicht Teil eines Storyboard-basierten UINavigationControllers ist, schlagen hier vor allem Methoden fehl. Ich bin auf diese Situation gestoßen und habe dann, um die Statusleiste auf Lichtstil zu setzen, folgendes verwendet

[self.navigationController.navigationBar setBarStyle:UIBarStyleBlack];

Das hat bei mir perfekt funktioniert.

Vishal Dharankar
quelle
7
Funktioniert nicht, wenn die Navigationsleiste Ihres Navigationscontrollers ausgeblendet ist.
MLQ
Ähnliches gilt für einen UISplitViewController. Am Ende habe ich Unterklassen.
Stephen Darlington
1
Nach meinem Verständnis UINavigationBar.barStyleüberschreibt preferredStatusBarStyle. Egal , wie Sie gesetzt preferredStatusBarStyle, ein verdammt `UINavigationBar.setBarStyle‘ übernimmt alles.
Desmond DAI
22

BEARBEITEN: Diese Lösung ist unter iOS 9 veraltet. Bitte wählen Sie eine der anderen Antworten.

Mit der UIViewControllerBasedStatusBarAppearanceEinstellung auf NEIN konnte ich den Stil auf weißen Text einstellen, indem ich Folgendes verwendete:

[UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleBlackTranslucent;

Dies liegt daran, dass die Textfarbe in diesem Stil unter iOS 6 und darunter weiß war.

UPDATE: Laut @jowie können Sie das unter iOS8 versuchen:

[UIApplication sharedApplication].statusBarStyle = UIBarStyleBlack;
Caulitomaz
quelle
Hast du die Frage sorgfältig gelesen? Er fragt nach der iOS7-Lösung und auch nach ihrem hellen Stil, der in Ihrem Fall nicht dunkel ist.
Vishal Dharankar
Es funktioniert unter iOS7. Ich habe es sorgfältig gelesen. Und beim UIBarStyleBlackTranslucent funktioniert es, weil dieser Stil unter iOS6 ein schwarzer Hintergrund (durchscheinend) mit weißem Text war. Wenn Sie dies unter iOS7 tun, wird der Text nur in Weiß angezeigt. Ich weiß, dass es hackisch aussieht, aber es war die einzige Möglichkeit, die Bar wirklich zu kontrollieren.
Caulitomaz
Verwenden Sie für iOS 8 UIBarStyleBlack.
Jowie
Danke @MatthieuRiegler, ich werde eine Mitteilung machen.
Caulitomaz
14

In Swift konnte ich dies tun, indem ich schrieb:

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

moreViewController.navigationBar.barStyle = UIBarStyle.Black

Grundsätzlich interessiert Sie die letzte Zeile.
Dies führte dazu, dass die Registerkartenleiste in Weiß geändert wurde:

Geben Sie hier die Bildbeschreibung ein

Beachten Sie, dass ich nichts geändert habe Info.plist, um dieses Ergebnis zu erzielen.
Weitere Informationen zum Ändern Navigation Status Barfinden Sie unter folgendem Link: http://www.appcoda.com/customize-navigation-status-bar-ios-7/

Fengson
quelle
Das funktioniert. Der neue "UIStatusBarStyleLightContent" wird jedoch nicht verwendet. Ich frage mich, ob es sich um eine zukunftssichere Lösung handelt. Lösen Sie immer noch das Problem!
Van Du Tran
1
Wäre eine gute Antwort gewesen, funktioniert aber nicht, wenn Ihre Navigationsleiste ausgeblendet ist.
MLQ
13

Geben Sie in der viewDidLoad-Methode Folgendes ein:

Ziel c

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

Schnell

UIApplication.shared.statusBarStyle = .lightContent
self.setNeedsStatusBarAppearanceUpdate()
Jota Freitas Jr.
quelle
Ich bin froh, Ihnen zu helfen Gagan
Jota Freitas Jr
Scheint seltsam, dass der Ansichts-Controller eine Eigenschaft für die gesamte Anwendung aktualisiert - die Lösung sollte entweder für die gesamte Anwendung (die in der Anwendung vorhanden ist AppDelegate) oder pro Ansichts-Controller sein.
Zorayr
schnelles Äquivalent dieser Methode UIApplication.sharedApplication (). setStatusBarStyle (UIStatusBarStyle.LightContent, animiert: false)
minhazur
Damit dies funktioniert, muss das Erscheinungsbild der View Controller-basierten Statusleiste in den Zieleigenschaften auf NO gesetzt werden. Ich denke, dies ist die beste Methode, weil sie einfach und offensichtlich ist.
n13
7

Ich wette, Sie haben Ihren View Controller in einen Navigationscontroller eingebettet. Um zu vermeiden, dass der Stil der Navigationsleiste für die .BlackVerwendung dieser Unterklasse festgelegt wird:

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

Schnell:

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

Ziel c:

Hängen Sie dies an die controller.mDatei viewDidLoad-Methode an:

[self setNeedsStatusBarAppearanceUpdate].

Implementieren Sie dann diese Methode in derselben controller.mDatei:

- (UIStatusBarStyle) preferredStatusBarStyle { 
    return UIStatusBarStyleLightContent; 
}

Offizielle Dokumente:

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

Artikel, den ich in meinem Blog geschrieben habe:

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

Darkseal
quelle
1

Im ViewController möchten Sie die Farbe der Statusleiste ändern

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

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

Schnelle Erweiterung dafür, weil ich immer vergesse, wie das funktioniert

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
quelle
0

Xcode 10.3,

In iPhone 8 12.4 Simulator ist es OK.

In iPhone X 12.4 Simulator habe ich alles oben versucht, nicht OK.

Dann füge ich es von Hand hinzu, Statusleiste besteht aus Zeit, Batterie, Handy.

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
quelle