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


79


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

Есть у кого-нибудь подсказка?

Я старался UIViewControllerBasedStatusBarAppearance

и

-(UIStatusBarStyle)preferredStatusBarStyle{ 
    return UIStatusBarStyleLightContent; 
}

но эти методы не работают.



1
И убедитесь, что панель навигации не должна перекрываться строкой состояния ....
— Rajneesh071

Я применил небольшой трюк для этого (и для управления видимым / скрытым состоянием) - я решил опубликовать его как pod 'UIViewController + ODStatusBar' ( cocoapods.org/pods/UIViewController+ODStatusBar )
— Alex Nazarsky

1
Это всего лишь один из десятков API-интерфейсов, поведение которых Apple случайным образом меняет от одной версии iOS к другой, и по какой-то причине не было полного восстания разработчиков. Вам нужно будет изменить свою реализацию, чтобы она соответствовала версии iOS, на которой работает ваше приложение, и тестировать ее каждый раз, когда вы создаете новую версию.
— Брон Дэвис

Ответы:


139

Вы пробовали это?

  1. Установите "Просмотр внешнего вида строки состояния на основе контроллера" ( UIViewControllerBasedStatusBarAppearance) YESв свой Info.plist. ( YESявляется значением по умолчанию, поэтому вы также можете просто не указывать это значение в своем списке.)

  2. В вашем методе viewDidLoad вызовите [self setNeedsStatusBarAppearanceUpdate].

  3. Реализуйте preferredStatusBarStyle, возвращая стиль строки состояния, который вы хотите для этого контроллера представления.

    - (UIStatusBarStyle) preferredStatusBarStyle { 
        return UIStatusBarStyleLightContent; 
    }
    

Мне не нужен был шаг 1,
— Ван Ду Тран

2
Это работает на Iphone 5 + ios7. UIViewControllerBasedStatusBarAppearance - НЕТ и [[UIApplication sharedApplication] setStatusBarStyle: UIStatusBarStyleBlackTranslucent]; отлично работает в моем случае :)
— Femina

4
@vishal работает с приложениями на основе UINavigationController, если вы поместите этот код в свой собственный подкласс UINavigationController
— anneblue

3
Вам не нужен 2-й шаг.
— pronebird 08

4
У меня не работает в iOS 8. Это просто меняет значение по умолчанию. То, что мне нужно, чтобы быть белым, теперь идет по умолчанию.
— noobsmcgoobs

74

Здесь есть уловка, если ваш контроллер представления находится внутри автономного UINavigationController, а не является частью UINavigationController, основанного на раскадровке, тогда, прежде всего, все методы терпят неудачу. Я столкнулся с этой ситуацией, а затем, чтобы установить в строке состояния светлый стиль, я использовал следующие

[self.navigationController.navigationBar setBarStyle:UIBarStyleBlack];

Это отлично сработало для меня.


7
Не работает, если панель навигации вашего контроллера навигации скрыта.
— MLQ

Аналогичный совет применим к UISplitViewController. В итоге я создал подклассы.
— Стивен Дарлингтон,

1
По моему мнению, UINavigationBar.barStyleотменяет preferredStatusBarStyle. Независимо от того, как вы устанавливаете preferredStatusBarStyle, один чертов `UINavigationBar.setBarStyle 'берет на себя все.
— Desmond DAI

22

РЕДАКТИРОВАТЬ: это решение устарело в iOS 9. Выберите один из других ответов.

С UIViewControllerBasedStatusBarAppearanceустановлен в NO, я был в состоянии установить стиль для белого текста с помощью:

[UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleBlackTranslucent;

Это связано с тем, что цвет текста в этом стиле был белым в iOS 6 и ниже.

ОБНОВЛЕНИЕ: согласно @jowie, вы можете попробовать это на iOS8:

[UIApplication sharedApplication].statusBarStyle = UIBarStyleBlack;

ты внимательно прочитал вопрос? Он просит решение для iOS7, а также его светлый стиль, а не темный, как в вашем случае.
— вишал дхаранкар

Работает на iOS7. Я внимательно его прочитал. Что касается UIBarStyleBlackTranslucent, он работает, потому что этот стиль на iOS6 был черным фоном (полупрозрачным) с белым текстом. Когда вы делаете это на iOS7, текст отображается только белым цветом. Я знаю, что это выглядит хакерским, но это был единственный способ по-настоящему контролировать панель.
— caulitomaz

Для iOS 8 используйте UIBarStyleBlack.
— jowie 04

Спасибо @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». Интересно, пригодится ли это решение в будущем? Все еще решаем проблему!
— Van Du Tran,

1
Было бы отличным ответом, но он не работает, если ваша панель навигации скрыта.
— MLQ

13

В методе viewDidLoad поместите это:

Цель C

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

Swift

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

Я рад помочь тебе, Гаган
— Йота Фрейтас-младший

Кажется странным, что контроллер представления обновляет свойство для всего приложения - решение должно быть либо для всего приложения (которое находится в AppDelegate), либо для каждого контроллера представления.
— Зорайр

быстрый аналог этого метода UIApplication.sharedApplication (). setStatusBarStyle (UIStatusBarStyle.LightContent, animated: false)
— minhazur

Для того, чтобы это работало, для отображения строки состояния на основе контроллера представления в целевых свойствах должно быть установлено значение НЕТ. Я считаю, что это лучший метод, потому что он простой и очевидный.
— n13

7

Готов поспорить, у вас есть контроллер представления, встроенный в контроллер навигации. Чтобы избежать настройки стиля панели навигации для .Blackиспользования этого подкласса:

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

5

Swift:

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.