iOS 7 і новіших версій: встановити стиль рядка стану для кожного контролера перегляду


79


Я спробував багато способів встановити стиль рядка стану (за замовчуванням або lightcontent), але не можу змусити його працювати на основі кожного контролера перегляду. Я можу встановити стиль рядка стану лише для всієї програми.

Хтось має підказку?

я намагався UIViewControllerBasedStatusBarAppearance

і

-(UIStatusBarStyle)preferredStatusBarStyle{ 
    return UIStatusBarStyleLightContent; 
}

але ці методи не працюють.



1
І переконайтеся, що панель навігації не повинна перекриватися рядком стану ....
Rajneesh071

Я використав для цього невеликий фокус (і для управління видимим / прихованим станом) - я вирішив опублікувати його як pod 'UIViewController + ODStatusBar' ( cocoapods.org/pods/UIViewController+ODStatusBar )
Алекс Назарський

1
Це лише один з десятків API, які Apple випадковим чином змінює поведінку від однієї версії iOS до наступної, і з якихось причин повне повстання розробників не відбулося. Вам доведеться змінювати свою реалізацію відповідно до версії iOS, на якій працює ваш додаток, і тестувати її кожного разу, коли ви створюєте нову версію.
Брон Девіс,

Відповіді:


139

Ви пробували це?

  1. Встановіть "Перегляд зовнішнього вигляду рядка стану на основі контролера" ( UIViewControllerBasedStatusBarAppearance) YESу вашому Info.plist. ( YESце значення за замовчуванням, тому ви також можете просто залишити це значення поза своїм списком.)

  2. У вашому методі viewDidLoad зателефонуйте [self setNeedsStatusBarAppearanceUpdate].

  3. Реалізуйте preferredStatusBarStyle, повернувши стиль рядка стану, який ви хочете для цього контролера подання.

    - (UIStatusBarStyle) preferredStatusBarStyle { 
        return UIStatusBarStyleLightContent; 
    }
    

Мені не потрібен був крок 1
Van Du Tran

2
Ця робота працює для Iphone 5 + ios7. UIViewControllerBasedStatusBarAppearance - НІ і [[UIApplication sharedApplication] setStatusBarStyle: UIStatusBarStyleBlackTranslucent]; чудово працює в моїй справі :)
Феміна

4
@vishal працює з програмами, заснованими на UINavigationController, якщо ви покладете цей код у свій власний підклас
UINavigationController

3
Вам не потрібен 2-й крок.
pronebird

4
Не працює у мене в iOS 8. Це просто змінює значення за замовчуванням. Те, що мені потрібно було білим, тепер переходить до типового.
noobsmcgoobs

74

Тут є фішка, якщо ваш контролер перегляду знаходиться всередині автономного UINavigationController, а не є частиною UINavigationController на основі Storyboard, тоді, перш за все, методи не вдаються. Я зіткнувся з цією ситуацією, а потім, щоб встановити рядок стану на легкий стиль, я використовував наступне

[self.navigationController.navigationBar setBarStyle:UIBarStyleBlack];

Для мене це чудово працювало.


7
Не працює, якщо панель навігації контролера навігації прихована.
MLQ

Подібна порада стосується UISplitViewController. Я закінчився підкласом.
Стівен Дарлінгтон,

1
На моє розуміння, UINavigationBar.barStyleперевизначає preferredStatusBarStyle. Як би ви не встановили preferredStatusBarStyle, один проклятий `UINavigationBar.setBarStyle 'бере на себе все.
Desmond DAI

22

EDIT: Це рішення застаріло для iOS 9. Будь ласка, виберіть одну з інших відповідей.

Коли UIViewControllerBasedStatusBarAppearanceвстановлено значення НІ, я зміг встановити стиль білого тексту, використовуючи:

[UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleBlackTranslucent;

Це пов’язано з тим, що колір тексту у цьому стилі був білим на iOS 6 і нижче.

ОНОВЛЕННЯ: Відповідно до @jowie, ви можете спробувати це на iOS8:

[UIApplication sharedApplication].statusBarStyle = UIBarStyleBlack;

ти уважно прочитав питання? Він просить рішення для iOS7, а також його світлий стиль, не темний, що є у вашому випадку.
vishal dharankar 02

Це працює на iOS7. Я його ретельно прочитав. А щодо UIBarStyleBlackTranslucent це працює, оскільки цей стиль на iOS6 мав чорний фон (напівпрозорий) з білим текстом. Коли ви робите це на iOS7, текст відображається лише білим кольором. Я знаю, що це виглядає хакерським, але це був єдиний спосіб, яким я дізнався, що справді контролюю бар.
caulitomaz

Для iOS 8 використовуйте UIBarStyleBlack.
jowie

Дякую @MatthieuRiegler, я винесу повідомлення.
caulitomaz

14

У Swift я зміг це зробити, написавши:

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

moreViewController.navigationBar.barStyle = UIBarStyle.Black

В основному вас цікавить останній рядок.
В результаті панель вкладок змінилася на білу:

введіть тут опис зображення

Зверніть увагу, що я нічого не змінив Info.plist, щоб досягти цього результату.
Для отримання додаткової інформації щодо змін Navigation Status Bar, будь ласка, перегляньте це посилання: http://www.appcoda.com/customize-navigation-status-bar-ios-7/


Це працює. Однак він не використовує новий "UIStatusBarStyleLightContent". Цікаво, чи це майбутнє рішення для перевірки? Все-таки виріши питання!
Ван Ду Тран

1
Це була б чудова відповідь, але не працює, якщо ваша навігаційна панель прихована.
MLQ

13

Для методу viewDidLoad поставте таке:

Завдання С

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

Стрімкий

UIApplication.shared.statusBarStyle = .lightContent
self.setNeedsStatusBarAppearanceUpdate()

Я радий допомогти вам Гаган
Джота Фрейтас-молодший

Дивно, що контролер подання оновлює властивість для всієї програми - рішення має бути або для всієї програми (яка живе в AppDelegate), або для контролера подання.
Zorayr

швидкий еквівалент цього методу UIApplication.sharedApplication (). setStatusBarStyle (UIStatusBarStyle.LightContent, animated: false)
minhazur

Для того, щоб це працювало, для вигляду рядка стану на основі контролера перегляду потрібно встановити значення НІ у цільових властивостях. Я думаю, що це найкращий метод, оскільки він простий і очевидний.
n13

7

Б'юсь об заклад, у вас є ваш контролер перегляду, вбудований у контролер навігації. Щоб уникнути встановлення стилю навігаційної панелі для .Blackвикористання цього підкласу:

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

5

Стрімкий:

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

Завдання C:

додайте це до controller.mметоду viewDidLoad:

[self setNeedsStatusBarAppearanceUpdate].

потім реалізуйте цей метод у тому ж controller.mфайлі:

- (UIStatusBarStyle) preferredStatusBarStyle { 
    return UIStatusBarStyleLightContent; 
}

Офіційні документи:

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

Стаття, яку я написав у своєму блозі:

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


1

У ViewController ви хочете змінити колір рядка стану

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

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

0

Швидке розширення для цього, тому що я завжди забуваю, як це працює

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()
    }
}

0

Xcode 10.3,

В iPhone 8 12.4 Simulator це нормально.

У iPhone X 12.4 Simulator я спробував усе вище, не гаразд.

Потім я додаю його від руки, рядок стану складається з часу, акумулятора, стільникового зв'язку.

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
    }

}


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.