Изменение цвета строки состояния для определенных ViewControllers с помощью Swift в iOS8

override func preferredStatusBarStyle() -> UIStatusBarStyle {
 return UIStatusBarStyle.LightContent;
}

Использование приведенного выше кода в любом ViewController для установки цвета statusBar на Белый для определенного viewcontroller не работает в iOS8 для меня. Какие-либо предложения? Используя метод UIApplication.sharedApplication, цвет меняется после необходимых изменений в Info.plist для всего приложения.

// Change the colour of status bar from black to white
UIApplication.sharedApplication().statusBarStyle = .LightContent

Как я могу просто внести изменения в цвет строки состояния для некоторых необходимых и определенных ViewControllers?

26 ответов

Решение

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

Первый шаг:

Откройте ваш info.plist и вставьте новый ключ с именем " Показать внешний вид строки состояния на основе контроллера ", чтобы НЕТ

Второй шаг (просто объяснение, нет необходимости реализовывать это):

Обычно мы помещаем следующий код в приложение (_:didFinishLaunchingWithOptions:) метод AppDelegate,

Swift 2

UIApplication.sharedApplication().statusBarStyle = .LightContent

Свифт 3

UIApplication.shared.statusBarStyle = .lightContent

но это влияет на statusBarStyle всех ViewControllers.

Итак, как заставить это работать для определенных ViewControllers - последний шаг:

Откройте файл viewcontroller, где вы хотите изменить statusBarStyle и поместите следующий код в viewWillAppear(),

Swift 2

UIApplication.sharedApplication().statusBarStyle = .LightContent

Свифт 3

UIApplication.shared.statusBarStyle = .lightContent

Кроме того, реализовать viewWillDisappear() метод для этого конкретного viewController и поместить следующие строки кода,

Swift 2

override func viewWillDisappear(animated: Bool) {
    super.viewWillDisappear(animated)
    UIApplication.sharedApplication().statusBarStyle = UIStatusBarStyle.Default

}

Свифт 3

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    UIApplication.shared.statusBarStyle = UIStatusBarStyle.default
}

Этот шаг сначала изменит statusBarStyle для конкретного viewcontroller, а затем измените его обратно на default когда конкретный viewcontroller исчезает. Не реализует viewWillDisappear() изменит statusBarStyle навсегда к новому определенному значению UIStatusBarStyle.LightContent

(По состоянию на 14 ноября 2018 г.)

Swift 4, Swift 4.2

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    self.setNeedsStatusBarAppearanceUpdate()
}
override var preferredStatusBarStyle : UIStatusBarStyle {
    return .lightContent
}

Решение Swift 4.2 с NavigationController

Первый шаг:

Откройте ваш info.plist и вставьте новый ключ с именем " Просмотр внешнего вида строки состояния на основе контроллера " в YES, чтобы позволить каждому VC использовать свое собственное свойство status.

Второй шаг

В каждом VC переопределите свойство prefeStatusBarStyle следующим образом:

override var preferredStatusBarStyle : UIStatusBarStyle {
    return .lightContent //.default for black style
}

Последний шаг

Переопределите свойство lovelyStatusBarStyle в своем пользовательском классе NavigationController:

class NavigationController : UINavigationController {

override func viewDidLoad() {
    super.viewDidLoad()
}

override var preferredStatusBarStyle : UIStatusBarStyle {

    if let topVC = viewControllers.last {
        //return the status property of each VC, look at step 2
        return topVC.preferredStatusBarStyle  
    }

    return .default
}

Я следовал этому уроку, и он работал для меня. Однако я не уверен, есть ли какие-либо предостережения.

https://coderwall.com/p/dyqrfa/customize-navigation-bar-appearance-with-swift

  • Откройте ваш info.plist и установитеUIViewControllerBasedStatusBarAppearance в false,
  • В первой функции в AppDelegate.swift, который содержит didFinishLaunchingWithOptions, установите цвет, который вы хотите.

UIApplication.sharedApplication().statusBarStyle = UIStatusBarStyle.LightContent

  • Обновление Swift 3 *

    UIApplication.shared.statusBarStyle =.lightContent

Здесь миллиард ответов, поэтому я подумал, почему бы не добавить еще одно в виде расширения (с помощью @Cœur)

Свифт 3

Расширение:

extension UIApplication {
    class var statusBarBackgroundColor: UIColor? {
        get {
            return (shared.value(forKey: "statusBar") as? UIView)?.backgroundColor
        } set {
            (shared.value(forKey: "statusBar") as? UIView)?.backgroundColor = newValue
        }
    }
}

Реализация:

UIApplication.statusBarBackgroundColor = .blue

В вашем Info.plist вам нужно определить внешний вид строки состояния на основе контроллера для любого значения.

Если вы определили его как YES, вам следует переопределить функцию предпочитаемое значение StatusBarStyle в каждом контроллере представления.

Если вы определите это НЕТ, тогда вы можете установить стиль в AppDelegate, используя

UIApplication.sharedApplication().setStatusBarStyle(UIStatusBarStyle.LightContent, animated: true)

Свифт 3

let statusBar: UIView = UIApplication.shared.value(forKey: "statusBar") as! UIView
if statusBar.responds(to: #selector(setter: UIView.backgroundColor)) {
  statusBar.backgroundColor = UIColor.black
} 

Это решение для установки цвета фона строки состояния для конкретного контроллера представления.

override func viewWillAppear(animated: Bool) {
    self.navigationController?.navigationBarHidden =  true

    UIApplication.sharedApplication().statusBarHidden = false
    UIApplication.sharedApplication().statusBarStyle = .LightContent

    let statusBar: UIView = UIApplication.sharedApplication().valueForKey("statusBar") as! UIView
    if statusBar.respondsToSelector("setBackgroundColor:") {
        statusBar.backgroundColor = UIColor.redColor()
    }

}

(По состоянию на 10 июня 2020 г.)

Swift 5 (без редактирования.Plistфайл)

Если вы используете Storyboard, перейдите в NavigationController, выберите navigationBar, нажми на Attributes Inspector, затем измените style. если тебе нужноlight content(белая строка состояния) установите что угодно, кромеdefault скажем, установить стиль black И если хочешь dark content (черная строка состояния) установите егоdefault.

По умолчанию (UIBarStyleDefault) приводит к темному переднему плану UIStatusBarStyleDefaultстатус бар. А такжеUIBarStyleBlack даст UIStatusBarStyleLightContent статус бар.

Программно

let nav = UINavigationController(rootViewController: rootViewController)

    nav.navigationBar.barStyle = .default //gives you dark Content status bar

    nav.navigationBar.barStyle = .black  //gives you light content status bar

Без панели навигации (Править.Plist)

Добавить UIViewControllerBasedStatusBarAppearance / View controller-based status bar appearance на ваш info.plist, а установленное значение true.

Override то preferredStatusBarStyle свойство в вашем контроллере

class ViewController: UIViewController {
    override var preferredStatusBarStyle : UIStatusBarStyle {
        return .lightContent
    }
}

SWIFT 2

Мне удалось успешно изменить внешний вид фона строки состояния, добавив в свой viewWillAppear следующее:

let statusBar: UIView = UIApplication.sharedApplication().valueForKey("statusBar") as! UIView

    if statusBar.respondsToSelector(Selector("setBackgroundColor:")) {
        statusBar.backgroundColor = .redColor()
    }

Воплощать в жизнь preferredStatusBarStyle как вы упомянули и позвоните self.setNeedsStatusBarAppearanceUpdate() в ViewDidLoad а также в наборе Info.plist UIViewControllerBasedStatusBarAppearance в YES (Это YES по умолчанию)

Непонятно, почему он не работает. Мне нужно проверить код. Еще одно предложение - перейти с рабочим кодом в viewDidLoadUIApplication.sharedApplication().statusBarStyle = .LightContent и измените это на значение по умолчанию, когда вы видите, исчезают viewWillDisappear,

Для быстрой 3

.plist

View controller-based status bar appearance = NO

AppDelegate.swift

  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Custom statubar
        UIApplication.shared.isStatusBarHidden = false
        UIApplication.shared.statusBarStyle = .lightContent
        let statusBar: UIView = UIApplication.shared.value(forKey: "statusBar") as! UIView
        statusBar.backgroundColor = UIColor.gray

        return true
    }

Все намного проще в Swift 3.0 Xcode 8

Используя код ниже в файле делегата приложения, после

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

вставить это:

UINavigationBar.appearance().barStyle = .black

UINavigationBar.appearance().barTintColor = UIColor(red: 230, green: 32, blue: 31, alpha: 1.0)

Свифт 3

//
//  LoginController.swift
//  Swift 3
//
//  Created by The Crab on 17/01/2017.
//  Copyright © 2017 Paxi Labs. All rights reserved.
//

import UIKit

class LoginController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        setNeedsStatusBarAppearanceUpdate()

        view.backgroundColor = UIColor(red: 61/255, green: 91/255, blue: 151/255, alpha: 1)

    }

    override var preferredStatusBarStyle: UIStatusBarStyle {
        return .lightContent
    }
}

Работает для навигационных приложений

    var addStatusBar = UIView()
    addStatusBar.frame = CGRectMake(0, 0, UIScreen.mainScreen().bounds.width, 20);
    addStatusBar.backgroundColor = global().UIColorFromRGB(0x65b4d9)
    self.window?.rootViewController?.view .addSubview(addStatusBar)

В моей ситуации я использую раскадровку для организации своих контроллеров представления. Я хочу изменить весь стиль строки состояния.

Вы можете увидеть на картинке ниже.

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

Stars View Controller является CPBaseNavigationController,а также CPBaseNavigationController это подкласс UINavigationController,

Я пытаюсь сделать следующие шаги:

  1. В AppDelegate.swift FUNC didFinishLaunchingWithOptions,добавлять

    //change status bar color
    UIApplication.sharedApplication().statusBarHidden = false
    UIApplication.sharedApplication().statusBarStyle = .LightContent
    

    но без эффекта.

  2. В StoryBoard найдите Base Tab BarController (картинка выше) Attributes Inspector, изменить Sattus Bar приписывать Light Content так плохо, никакого эффекта.

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

  1. Последнее, что я понял. В моем собственном навигационном контроллере CPBaseNavigationController, добавь func preferredStatusBarStyle

    override func preferredStatusBarStyle() -> UIStatusBarStyle {
       return .LightContent
    }
    

    Это работает хорошо!

Кроме того, statusBarStyle устарела в 9.0, вы можете использовать -[UIViewController preferredStatusBarStyle] ,

Другой действительно простой способ сделать это - просто создать расширение класса UINavigationController.

С переопределением preferredStatusBarStyle: метод не будет работать, если мы не сделаем это внутри класса UINavigationController.

extension UINavigationController {
open override var preferredStatusBarStyle: UIStatusBarStyle {
    return .lightContent
}

}

Swift 4 Для конкретного ViewController без встроенной навигации ViewController просто добавьте это в свой файл ViewController.

override var preferredStatusBarStyle : UIStatusBarStyle {
    return .lightContent
}

В Swift 5 или xcode 11 и более поздних версиях установите (Просмотр внешнего вида строки состояния на основе контроллера) ключ в info.plist как НЕТ Затем перейдите к цели проекта и выберите общий, Установите стиль строки состояния на темный или светлый

Пользовательский цвет для строки состояния (iOS11+, Swift4+)

Если вы ищете решение, как изменить цвет строки состояния на свой собственный цвет, это рабочее решение.

let statusBarView = UIView()
view.addSubview(statusBarView)
statusBarView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
    statusBarView.topAnchor.constraint(equalTo: view.topAnchor),
    statusBarView.leftAnchor.constraint(equalTo: view.leftAnchor),
    statusBarView.rightAnchor.constraint(equalTo: view.rightAnchor),
    statusBarView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor)
])
statusBarView.backgroundColor = .blue

У меня были некоторые проблемы с этим. Мне не очень понравилось, что глобальное изменение цвета строки состояния появилось, а затем его изменение на экране исчезло, как принятый ответ. Хотите верьте, хотите нет, но вы можете заставить это работать, переопределив preferredStatusBarStyle на желаемом контроллере просмотра. Спустя много времени, это то, что я сделал, чтобы заставить его работать:

  1. Изменить вид строки состояния на основе контроллера в вашем info.plist ДА.
  2. Теперь любой контроллер полноэкранного просмотра может изменить стиль строки состояния, переопределив preferredStatusBarStyle,
  3. Я задаю полный экран, потому что это не будет работать для (не полноэкранных) контроллеров модального представления, не без настройки modal​Presentation​Captures​Status​Bar​Appearance Да, это так.
  4. Также, если у вас есть встроенные контроллеры представления, как, например, в контроллере навигации, он будет запрашивать самый верхний контроллер представления для стиля строки состояния. Переопределение child​View​Controller​For​Status​Bar​Style и прохождение встроенного контроллера представления должно работать, но это не для меня. Поэтому я просто вернул предпочтительную строку состояния встроенных контроллеров представления в качестве предпочтительного стиля строки состояния. Что-то вроде этого:

    override var preferredStatusBarStyle: UIStatusBarStyle {
         if let topViewController = viewControllers.last {
             return topViewController.preferredStatusBarStyle
         }
    
         return .default
    }
    

Я установил определенный цвет (в формате RGB), используя приведенный ниже код в App Delegate файл:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
. . .

 UIApplication.sharedApplication().statusBarHidden = false
        UIApplication.sharedApplication().statusBarStyle = .LightContent

        let statusBar: UIView = UIApplication.sharedApplication().valueForKey("statusBar") as! UIView
        if statusBar.respondsToSelector(Selector("setBackgroundColor:")) {
            statusBar.backgroundColor = UIColor.init(red: 0.1, green: 0.27, blue: 0.60, alpha: 1.0)
        }

. . .
}

Вы также должны добавить ниже, введите Info.plist файл:

Просмотр внешнего вида строки состояния контроллера с логическим значением, установленным на NO

Снимок экрана 1

Снимок экрана 2

Я могу предложить вам более простой способ,

  1. Просто вызовите setNeedsStatusBarAppearanceUpdate в viewDidLoad, как сказано в документации Apple:

Вызывайте этот метод, если изменяются атрибуты строки состояния контроллера представления, такие как скрытый / скрытый статус или стиль. Если вы вызываете этот метод в блоке анимации, изменения анимируются вместе с остальной частью блока анимации.

  1. Реализуйте предпочитаемый тип StatusBarStyle, возвращающий предпочитаемый вами тип.

У меня это работало в iOS 10.1.

Цель С

[self setNeedsStatusBarAppearanceUpdate];

-(UIStatusBarStyle)preferredStatusBarStyle {
     return UIStatusBarStyleLightContent;
}

стриж

setNeedsStatusBarAppearanceUpdate()

var preferredStatusBarStyle: UIStatusBarStyle { 
    return .lightContent
}

Я удивлен, что никто не указал на это. В любом случае наслаждайтесь:)

В Swift 4 или 4.2

Вы можете добавить на свой vc

предпочитаемый StatusBarStyle

и установите возвращаемое значение на

.lightContent или.default

пример:

override var preferredStatusBarStyle: UIStatusBarStyle {
        return .lightContent
}

Что работало со мной, в раскадровке перейдите к контроллеру навигации, выберите панель навигации, нажмите инспектор атрибутов, затем измените стиль с по умолчанию на черный. Это оно!

Обновление Swift 3.0

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

        UIApplication.shared.statusBarStyle = .lightContent

        return true
    }

Возможны две ситуации:

1. показать панель навигации

1) добавить1UIViewControllerBasedStatusBarAppearance / View controller-based status bar appearance на ваш info.plist, а установленное значение true.

2) Переопределите свойство primaryStatusBarStyle в своем пользовательском классе NavigationController: (из @guillama)

class NavigationController : UINavigationController {

    override var preferredStatusBarStyle : UIStatusBarStyle {

    if let topVC = viewControllers.last {
        //return the status property of each VC, look at step 2
        return topVC.preferredStatusBarStyle  
    }
        return .default
    }

3) override (переопределить) preferredStatusBarStyle в вашем конкретном контроллере представления:

override var preferredStatusBarStyle : UIStatusBarStyle {
    return .lightContent
}

2. скрытая панель навигации

1) ditto (то же самое)

2) второй шаг выше не нужен, третий шаг следует реализовать напрямую.

override var preferredStatusBarStyle : UIStatusBarStyle {
    return .lightContent
}

SWIFT 4.2 Привет, я хотел бы поделиться решением, которое сработало для меня, которое я получил из отличной статьи Грейг Груммитта на эту захватывающую тему.

Шаг 1 Как уже упоминалось ниже, ДОБАВЬТЕ в свой PLIST

View controller-based status bar appearance YES

Шаг 2 в RootViewcontroller добавить ниже

var statusBarHidden: Bool = false {
        didSet(newValue) {
            UIView.animate(withDuration: 0.1) {
                self.setNeedsStatusBarAppearanceUpdate()
            }
        }
    }

    override var prefersStatusBarHidden: Bool {
        return statusBarHidden
    }

    var vcStatusBarStyle: UIStatusBarStyle = .default {
        didSet(newValue) {
            UIView.animate(withDuration: 0.1) {
                self.setNeedsStatusBarAppearanceUpdate()
            }
        }
    }

    override var preferredStatusBarStyle: UIStatusBarStyle {
        return vcStatusbarStyle
    }

При обновлении любого свойства statusBarHidden или же vcStatusBarStyle это позвонит setNeedsStatusBarAppearanceUpdate() и обновит строку состояния новыми значениями для любого prefersStatusBarHidden или же preferredStatusBarStyle, В моей ситуации мне пришлось обновить эти свойства для контейнера viewcontroller, который был родителем видимого childviewcontroller. Я сделал это с помощью простого метода делегата.

protocol MainViewControllerDelegate {
    func updateStatusBarStyle(statBarStayle: UIStatusBarStyle)
    func toggleStatusBar(visable: Bool)
}

Конечно, при создании экземпляра childViewController(Visible VC) не забудьте установить MainViewcontroller(Container VC) в качестве его делегата. Я иногда делаю.:)

childViewController.delegate = self

Затем в childViewController я просто вызвал метод делегата, когда необходимо обновить строку состояния.

self.delegate?.updateStatusBarStyle(statBarStayle: .default)

Как упоминалось выше, Грейг Груммитт более подробно рассказывает об этом решении, а также о работе с UINavigationControllers. Ссылка здесь: таинственный случай строки состояния

Я использую этот способ в Swift 5, Swift 4.2.

Добавьте в Info.plist следующие значения:

UIViewControllerBasedStatusBarAppearance = ДА

или

UIViewControllerBasedStatusBarAppearance = NO (чтобы увидеть изменения)

UIStatusBarHidden = NO

UIStatusBarStyle = UIStatusBarStyleDefault (или установите значение UIStatusBarStyleLightContent, если вы хотите видеть световые тексты строки состояния при запуске)

Затем поместите код ниже в определенные контроллеры представления, где вы хотите видеть светлое содержимое (чтобы видеть темные тексты, установите для предпочтительного StatusBarStyle значение .darkContent).

override var preferredStatusBarStyle: UIStatusBarStyle {
    return .lightContent
}

override func viewDidLoad() {
    super.viewDidLoad()

    if let statusBar: UIView = UIApplication.shared.value(forKey: "statusBar") as? UIView {
        statusBar.backgroundColor = .sunflowerYellow
    }
}

Нажмите на группу "Вспомогательные файлы" (слева вверху - название вашего проекта). Перейдите к информации. Нажмите + где-то между списками, как показано ниже названия пакета. Добавьте "Просмотр внешнего вида строки состояния на основе контроллера" и установите для него значение "НЕТ". Затем откройте AppDelegate.swift и измените его следующим образом:

func application(application: UIApplication!, didFinishLaunchingWithOptions launchOptions: NSDictionary!) -> Bool {

UIApplication.sharedApplication().setStatusBarStyle(UIStatusBarStyle.LightContent, animated: true)

return true
}

Это оно.

Другие вопросы по тегам