iOS 7 i nowsze: ustaw styl paska stanu dla kontrolera widoku

79


Próbowałem na wiele sposobów ustawić styl paska stanu (domyślny lub lekki), ale nie mogę go uruchomić na podstawie kontrolera widoku. Mogę ustawić styl paska stanu tylko dla całej aplikacji.

Czy ktoś ma podpowiedź?

próbowałem UIViewControllerBasedStatusBarAppearance

i

-(UIStatusBarStyle)preferredStatusBarStyle{ 
    return UIStatusBarStyleLightContent; 
}

ale te metody nie działają.

Van Du Tran
źródło
1
I upewnij się, że pasek nawigacji nie powinien nachodzić na pasek stanu ....
Rajneesh071
Użyłem do tego małej sztuczki (i kontrolowania widocznego / ukrytego stanu) - postanowiłem opublikować go jako pod 'UIViewController + ODStatusBar' ( cocoapods.org/pods/UIViewController+ODStatusBar )
Alex Nazarsky
1
To tylko jeden z kilkudziesięciu interfejsów API, które Apple losowo zmienia zachowanie z jednej wersji systemu iOS na drugą iz jakiegoś powodu nie doszło do pełnego buntu programistów. Będziesz musiał zmodyfikować swoją implementację, aby pasowała do wersji systemu iOS, na której działa Twoja aplikacja, i testować ją za każdym razem, gdy tworzysz nowszą wersję.
Bron Davies

Odpowiedzi:

139

Czy próbowałeś tego?

  1. Ustaw opcję „Wyświetl wygląd paska stanu opartego na kontrolerze” ( UIViewControllerBasedStatusBarAppearance) YESw Info.plist. ( YESjest wartością domyślną, więc możesz też po prostu pozostawić tę wartość poza swoją plistą).

  2. W metodzie viewDidLoad wywołaj [self setNeedsStatusBarAppearanceUpdate].

  3. Zaimplementuj preferredStatusBarStyle, zwracając styl paska stanu, który chcesz dla tego kontrolera widoku.

    - (UIStatusBarStyle) preferredStatusBarStyle { 
        return UIStatusBarStyleLightContent; 
    }
    
Greg
źródło
Nie potrzebowałem kroku 1 tho
Van Du Tran
2
To działa dla Iphone 5 + ios7. UIViewControllerBasedStatusBarAppearance ma wartość NO i [[UIApplication sharedApplication] setStatusBarStyle: UIStatusBarStyleBlackTranslucent]; działa dobrze w moim przypadku :)
Femina
4
@vishal współpracuje z aplikacjami opartymi na UINavigationController, jeśli umieścisz ten kod w niestandardowej podklasie UINavigationController
anneblue
3
Nie potrzebujesz drugiego kroku.
Ben Affleck
4
Nie działa dla mnie w iOS 8. To po prostu zmienia ustawienie domyślne. To, co musiałem być biały, teraz przechodzi do ustawień domyślnych.
noobsmcgoobs
74

Jest tu pewien haczyk, jeśli kontroler widoku znajduje się w autonomicznym UINavigationController i nie jest częścią UINavigationController opartego na Storyboard, to przede wszystkim zawodzą metody. Natknąłem się na tę sytuację, a następnie, aby ustawić pasek stanu na styl światła, użyłem następującego

[self.navigationController.navigationBar setBarStyle:UIBarStyleBlack];

To zadziałało idealnie dla mnie.

vishal dharankar
źródło
7
Nie działa, jeśli pasek nawigacyjny kontrolera nawigacji jest ukryty.
MLQ
Podobna rada dotyczy UISplitViewController. Skończyło się na podklasie.
Stephen Darlington
1
Według mojego zrozumienia UINavigationBar.barStylezastępuje preferredStatusBarStyle. Bez względu na to, jak ustawisz preferredStatusBarStyle, jeden cholerny `UINavigationBar.setBarStyle 'przejmuje wszystko.
Desmond DAI
22

EDYTUJ: To rozwiązanie jest przestarzałe w systemie iOS 9. Wybierz jedną z pozostałych odpowiedzi.

Po UIViewControllerBasedStatusBarAppearanceustawieniu na NIE mogłem ustawić styl na biały tekst za pomocą:

[UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleBlackTranslucent;

Dzieje się tak, ponieważ kolor tekstu w tym stylu był biały na iOS 6 i starszych.

AKTUALIZACJA: Według @jowie możesz to wypróbować na iOS8:

[UIApplication sharedApplication].statusBarStyle = UIBarStyleBlack;
caulitomaz
źródło
czy uważnie przeczytałeś pytanie? Prosi o rozwiązanie iOS7, a także jego jasny styl, a nie ciemny, co jest w twoim przypadku.
vishal dharankar
Działa na iOS7. Przeczytałem uważnie. A jeśli chodzi o UIBarStyleBlackTranslucent, działa, ponieważ ten styl na iOS6 miał czarne tło (półprzezroczyste) z białym tekstem. Kiedy robisz to na iOS7, wyświetla tylko tekst w kolorze białym. Wiem, że wygląda na zepsuty, ale był to jedyny sposób, w jaki dowiedziałem się, że mogę naprawdę kontrolować pasek.
caulitomaz
W przypadku iOS 8 użyj UIBarStyleBlack.
jowie
Dzięki @MatthieuRiegler, wystawię powiadomienie.
caulitomaz
14

W Swift mogłem to zrobić pisząc:

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

moreViewController.navigationBar.barStyle = UIBarStyle.Black

Zasadniczo interesuje Cię ostatnia linia.
Spowodowało to zmianę paska zakładek na biały:

wprowadź opis obrazu tutaj

Zauważ, że nic nie zmieniłem Info.plist, aby osiągnąć ten wynik.
Aby uzyskać więcej informacji dotyczących zmian Navigation Status Bar, sprawdź ten link: http://www.appcoda.com/customize-navigation-status-bar-ios-7/

Fengson
źródło
To działa. Jednak nie używa nowego „UIStatusBarStyleLightContent”, zastanawiam się, czy jest to przyszłościowe rozwiązanie? Nadal rozwiąż problem!
Van Du Tran
1
Byłaby to świetna odpowiedź, ale nie działa, jeśli pasek nawigacji jest ukryty.
MLQ
13

W metodzie viewDidLoad umieść to:

Cel C

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

Szybki

UIApplication.shared.statusBarStyle = .lightContent
self.setNeedsStatusBarAppearanceUpdate()
Jota Freitas Jr
źródło
Cieszę się, że mogę ci pomóc Gagan
Jota Freitas Jr
Wydaje się dziwne, że kontroler widoku aktualizuje właściwość dla całej aplikacji - rozwiązanie powinno dotyczyć całej aplikacji (która znajduje się w AppDelegate) lub dla każdego kontrolera widoku.
Zorayr
szybki odpowiednik tej metody UIApplication.sharedApplication (). setStatusBarStyle (UIStatusBarStyle.LightContent, animated: false)
minhazur
Aby to zadziałało, wygląd paska stanu widoku kontrolera musi być ustawiony na NIE we właściwościach docelowych. Myślę, że to najlepsza metoda, ponieważ jest prosta i oczywista.
n13
7

Założę się, że kontroler widoku jest wbudowany w kontroler nawigacji. Aby uniknąć ustawiania stylu paska nawigacji do .Blackużywania tej podklasy:

class YourNavigationController: UINavigationController {
    override func childViewControllerForStatusBarStyle() -> UIViewController? {
        return topViewController
    }
}
SoftDesigner
źródło
5

Szybki:

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

Cel C:

dołącz to do controller.mmetody viewDidLoad pliku:

[self setNeedsStatusBarAppearanceUpdate].

następnie zaimplementuj tę metodę w tym samym controller.mpliku:

- (UIStatusBarStyle) preferredStatusBarStyle { 
    return UIStatusBarStyleLightContent; 
}

Oficjalne dokumenty:

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

Artykuł, który napisałem na swoim blogu:

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

Darkseal
źródło
1

W kontrolerze ViewController, w którym chcesz zmienić kolor paska stanu

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

- (void) viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
}
jxdwinter
źródło
0

Szybkie rozszerzenie, ponieważ zawsze zapominam, jak to działa

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
źródło
0

Xcode 10.3,

W symulatorze iPhone'a 8 12.4 jest OK.

W symulatorze iPhone X 12.4 próbowałem wszystkiego powyżej, nie OK.

Następnie dodaję ręcznie, pasek stanu składa się z czasu, baterii, komórki.

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
źródło