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];

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

Vishal Dharankar
источник
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/

Fengson
источник
Это работает. Однако он не использует новый «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
    }
}
SoftDesigner
источник
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/

Darkseal
источник
1

В ViewController, который вы хотите изменить цвет строки состояния

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

- (void) viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
}
jxdwinter
источник
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()
    }
}
n13
источник
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
    }

}


dengApro
источник