Как установить стиль строки состояния в Swift 3

Я использую Xcode 8.0 beta 4.

В предыдущей версии UIViewController имеет метод установки стиля строки состояния

public func preferredStatusBarStyle() -> UIStatusBarStyle

Однако, я нашел, что это изменилось на "Получить ТОЛЬКО варивацию" в Swift 3.

public var preferredStatusBarStyle: UIStatusBarStyle { get } 

Как обеспечить стиль для использования в моем UIViewController?

Ответ 1

[ОБНОВЛЕНО] Для Xcode 10+ и Swift 4. 2+

Это предпочтительный метод для iOS 7 и выше

В приложении Info.plist установите для параметра View controller-based status bar appearance значение YES.

Переопределите preferredStatusBarStyle элемент preferredStatusBarStyle (Apple docs) в каждом из ваших контроллеров представления. Например:

override var preferredStatusBarStyle: UIStatusBarStyle {     
      return .lightContent
}

Если вы preferredStatusBarStyle возвращающий другой предпочтительный стиль строки состояния, основанный на чем-то, что изменяется внутри вашего контроллера представления (например, позиция прокрутки или отображаемое изображение темное), тогда вы захотите вызвать setNeedsStatusBarAppearanceUpdate() когда это состояние изменения.

iOS до версии 7, устаревший метод

Apple это устарела, поэтому она будет удалена в будущем. Используйте описанный выше метод, чтобы вам не приходилось переписывать его при выходе следующей версии iOS.

Если ваше приложение будет поддерживать В вашем приложении Info.plist установите для параметра View controller-based status bar appearance значение NO.

В appDelegate.swift, функция didFinishLaunchingWithOptions, добавьте:

UIApplication.shared.statusBarStyle = .lightContent

Для контроллера навигации

Если вы используете контроллер навигации и хотите, чтобы предпочтительный стиль строки состояния каждого контроллера представления использовался, и установите View controller-based status bar appearance на YES в вашем приложении info.plist

extension UINavigationController {
   open override var preferredStatusBarStyle: UIStatusBarStyle {
      return topViewController?.preferredStatusBarStyle ?? .default
   }
}

Ответ 2

Последнее обновление (Xcode 10+/Swift 4. 2+)

Эта статья оставлена без изменений для тех, кто хочет понять логику различных подходов, которые присутствовали в течение последних нескольких лет. Между тем, начиная с Xcode 10, первый подход Swift 4.2 устарел и больше не поддерживается (т.е. не вступит в силу, если вы попытаетесь использовать его). Он по-прежнему ссылается на вашу информацию, чтобы лучше понять причины, лежащие в Plist.info флага Plist.info и практики настройки.

Важное уточнение

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

Первый подход - один цвет для всего приложения (УСТАРЕЛО начиная с iOS7)

В info.plist вы найдете или создадите ключ с именем

View controller-based status bar appearance

и установите его в NO.

Что оно делает? По сути, он устанавливает параметр, который говорит, что в вашем приложении внешний вид строки состояния не определяется индивидуально каждым контроллером представления. Это очень важно понять. Это означает, что у вас есть единые настройки для всего приложения, для всех экранов. Существует две настройки: по default - черный текст на белом фоне или lightContent - белый текст на черном фоне.

Чтобы настроить один из них (один параметр для всех экранов):

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    application.statusBarStyle = .lightContent // .default
    return true
}

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

Второй подход - индивидуальный цвет для каждого контроллера вида

Это наоборот. Чтобы заставить его работать, перейдите к info.plist и установите

View controller-based status bar appearance

в ДА

Таким образом, всякий раз, когда новый контроллер представления открыт, стиль строки состояния устанавливается индивидуально, если вы вставляете эту реализацию в каждый экземпляр UIViewController вам нужен:

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

У вас так же, как в первом, установить темный или светлый стиль для строки состояния, индивидуально для каждого контроллера представления.

Это свойство выбирается UIKit в двух сценариях:

  1. При инициализации экрана, когда готовится пользовательский интерфейс.
  2. После вызова setNeedsStatusBarAppearanceUpdate() в коде.

В последнем случае вы имеете право манипулировать внешним видом строки состояния с помощью следующего кода:

var isDark = false {
    didSet {
        setNeedsStatusBarAppearanceUpdate()
    }
}

override var preferredStatusBarStyle: UIStatusBarStyle {
    return isDark ? .lightContent : .default
}

func toggleAppearance() {
   isDark.toggle()
}

Затем, всякий раз, когда вы вызываете toggleAppearance(), происходит изменение стиля строки состояния.

Третий подход - взломать!

Есть взлом, который позволяет получить доступ к строке состояния напрямую:

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

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

    return true
}

Зачем взламывать? Если вам нужен цвет строки состояния, отличный от черного или белого, вы используете недокументированный API. Вы получаете объект statusBar используя KVC, и устанавливаете его цвет фона. Объект, который вы получаете таким способом, - UIStatusBar, который является производным от UIView и, таким образом, естественно поддерживает свойство backgroundColor. Это грязный, недопустимый способ, но пока это единственный способ установить пользовательский цвет для строки состояния (не принимая во внимание подход UINavigationBar, который позволяет полностью настроить внешний вид панели навигации и строки состояния). Это может привести к отклонению вашего приложения. Но, возможно, тебе повезло. И если это так, в некоторых сложных обстоятельствах (таких как иерархия вложенных, дочерних контроллеров и контроллеров представления) это может быть в значительной степени единственным или, по крайней мере, менее сложным способом настройки внешнего вида строки состояния (например, чтобы сделать ее прозрачной)

Xcode 10+, Swift 4.2

Альтернатив больше нет: разработчик должен позволить каждому контроллеру представления определять внешний вид строки состояния, устанавливая флаг в значение YES (или опуская это действие, потому что это YES по умолчанию) и следуя приведенным выше инструкциям.


бонус

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

extension UIViewController {
    func setStatusBarStyle(_ style: UIStatusBarStyle) {
        if let statusBar = UIApplication.shared.value(forKey: "statusBar") as? UIView {
            statusBar.backgroundColor = style == .lightContent ? UIColor.black : .white
            statusBar.setValue(style == .lightContent ? UIColor.white : .black, forKey: "foregroundColor")
        }
    }
}

Ответ 3

Вы можете попробовать переопределить возвращаемое значение, а не устанавливать его. Метод объявляется как {get}, поэтому просто укажите getter:

 override var preferredStatusBarStyle: UIStatusBarStyle {
    return .lightContent
}

Если вы установите это условно, вам нужно вызвать setNeedsStatusBarAppearanceUpdate(), чтобы он изменил его, когда вы будете готовы

Ответ 4

Swift 3 и 4, iOS 10 и 11, Xcode 9 и 10
Для меня этот метод не работает:

override var preferredStatusBarStyle: UIStatusBarStyle {
    return .lightContent
}

когда я привык к каждому контроллеру представления, но это работало:

  • В файле info.list добавьте строку: View controller-based status bar appearance и установите значение NO

  • Далее в приложении:

    UIApplication.shared.statusBarStyle = .lightContent
    

Ответ 5

Если вы хотите изменить цвет statusBar на белый, для всех представлений, содержащихся в UINavigationController, добавьте это внутри AppDelegate:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.

    UINavigationBar.appearance().barStyle = .blackOpaque
    return true
}

Этот код:

override var preferredStatusBarStyle: UIStatusBarStyle {
    return .lightContent
}

не работает для UIViewControllers, содержащегося в UINavigationController, потому что компилятор ищет statusBarStyle UINavigationController, а не для statusBarStyle ViewControllers содержащиеся в нем.

Надеюсь, это поможет тем, кто не смог с принятым ответом!

Ответ 6

В файле Info.plist вам нужно добавить ключ ниже:

View controller-based status bar appearance с булевым значением, установленным в NO

В классе appdelegate, в didFinishLaunchingWithOptions перед возвратом.

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

измените backgroundColor и statusBarStyle согласно требованию.

Ответ 7

Если вы хотите изменить стиль строки состояния в любое время после появления представления, вы можете использовать это:

  • В файле info.list добавьте строку: Просмотрите внешний вид строки состояния на основе контроллера и установите для нее ДА

    var viewIsDark = Bool()
    
    func makeViewDark() {
    
        viewIsDark = true
        setNeedsStatusBarAppearanceUpdate()
    }
    
    func makeViewLight() {
    
        viewIsDark = false
        setNeedsStatusBarAppearanceUpdate()
    }
    
    override var preferredStatusBarStyle: UIStatusBarStyle {
    
        if viewIsDark {
            return .lightContent 
        } else {
            return .default 
        } 
    }
    

Ответ 8

Вы также можете сделать это в раскадровке

  • Создайте новую запись в info.plist "Просмотр состояния панели управления на основе контроллера" установите ее в "YES".
  • Перейдите в свою раскадровку и выберите навигационный контроллер, который вы хотите изменить. Нажмите на панель навигации из раздела "Структура раскадровки" (левая панель на раскадровке).
  • Перейдите в правую панель и щелкните раздел атрибутов
  • В разделе "Панель навигации" вы увидите стиль. Выберите стиль, который вы хотите (по умолчанию черный, а черный - белый)

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

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

(Выполнено с Xcode 8.3.3 во всем проекте Swift)

Ответ 9

Сначала вам нужно добавить строку с ключом: View controller-based status bar appearance и значение NO в Info.plist файл. После этого добавьте 2 функции в ваш контроллер к конкретному только контроллеру:

override func viewWillAppear(_ animated: Bool) {
       super.viewWillAppear(animated)
       UIApplication.shared.statusBarStyle = .lightContent
}

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

Ответ 10

Swift 3

В Info.plist добавьте строку под названием "Просмотр состояния панели управления на основе контроллера" и установите ее значение No.

class YourViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        UIApplication.shared.statusBarStyle = .lightContent //or .default
        setNeedsStatusBarAppearanceUpdate()

    }

}

Ответ 11

Кажется, есть небольшая проблема с цветом текста строки состояния при работе с панелями навигации.

Если вы хотите, чтобы для записи .plist в качестве внешнего вида строки состояния на контроллере было задано значение YES, оно иногда не будет работать, если у вас есть цветная навигационная панель.

Например:

override func viewWillAppear(_ animated: Bool) {
    let nav = self.navigationController?.navigationBar
    nav?.barTintColor = .red
    nav?.tintColor = .white
    nav?.titleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white]
    setNeedsStatusBarAppearanceUpdate()
}

а также

override var preferredStatusBarStyle: UIStatusBarStyle {return.lightContent}

Приведенный выше код не будет работать, даже если вы установили следующее в AppDelegate:

UIApplication.shared.statusBarStyle =.lightContent

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

nav?.barStyle = UIBarStyle.black

Когда стиль бара черный, он слушает вашу переопределенную переменную. Надеюсь, это поможет кому-то :)

Ответ 12

Xcode 8.3.1, Swift 3.1

  • Создайте новую запись в info.plist "Просмотр состояния панели управления на основе контроллера" установите ее в "НЕТ".

  • Откройте AppDelegate.swift и добавьте эти строки в метод "didFinishLaunchingWithOptions":

application.statusBarStyle =.lightContent

Ответ 13

Для людей, которые хотят изменить строку состояния для всех контроллеров представления на: iOS 11, решение Swfit 4 довольно просто.

1) Info.plist добавить:

Просмотреть внешний вид строки состояния на основе контроллера → НЕТ

2) Левая сторона проекта XCode slect> Цели > Выберите проект> В разделе "Общие"> "Информация о развертывании"> Выбрать стиль строки состояния: свет

Если вы хотите изменить строку состояния только для одного viewcontroller, на viewDidLoad добавьте:

override var preferredStatusBarStyle : UIStatusBarStyle {
    return .lightContent
}

Ответ 14

Xcode 10 или позже

Код не требуется, просто следуйте инструкциям ниже.

Если вы хотите изменить строку состояния во всем приложении.

  1. Выберите Project из Project Navigator (Левая боковая панель).
  2. Выберите цель.
  3. Выберите вкладку "Общие".
  4. Найти информацию о развертывании.
  5. Изменить стиль строки состояния на Светлый (для темного фона "Светлый", Светлый фон "По умолчанию")

Не забыл изменения info.plist

  1. Выберите вкладку Информация
  2. Добавьте этот ключ в ваш plist файл "Просмотр внешнего вида строки состояния на основе контроллера" = НЕТ

Запустите свой проект и проверьте его.

Мой проект в Swift 5 и Xcode 10.2

Ответ 15

Swift 4.0 Используйте этот код в "doneFinishLaunchingWithOptions launchOptions:" Класс appdelegate

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

Ответ 16

Вот Apple Guidelines/Инструкция по изменению стиля строки состояния.

Если вы хотите установить стиль строки состояния, уровень приложения, тогда установите для UIViewControllerBasedStatusBarAppearance значение NO в вашем файле .plist. А в ваш appdelegate > didFinishLaunchingWithOptions добавьте следующий didFinishLaunchingWithOptions (программно вы можете сделать это из делегата приложения).

Цель С

[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent animated:YES];

стриж

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    application.statusBarStyle = .lightContent
    return true
}

если вы хотите установить стиль строки состояния, на уровне контроллера представления выполните следующие действия:

  1. Установите для UIViewControllerBasedStatusBarAppearance значение YES в файле .plist, если вам нужно установить стиль строки состояния только на уровне UIViewController.
  2. В viewDidLoad добавить функцию - setNeedsStatusBarAppearanceUpdate

  3. переопределите предпочитаемый элемент StatusBarStyle в вашем контроллере представления.

Цель С

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self setNeedsStatusBarAppearanceUpdate];
}

- (UIStatusBarStyle)preferredStatusBarStyle
{
    return UIStatusBarStyleLightContent;
}

стриж

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

override var preferredStatusBarStyle: UIStatusBarStyle {
    return .lightContent
}

Установите значение .plist в соответствии с уровнем настройки стиля строки состояния.

enter image description here

Ответ 17

Чтобы добавить в большой ответ @Krunal fooobar.com/questions/77698/...

В случае, если вы используете UINavigationController, preferredStatusBarStyle UIViewController не будет влиять на UIViewController.

Xcode 10 и Swift 4.

Установить пользовательский UINavigationController

Пример:

class LightNavigationController: UINavigationController {

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

Используйте расширение для решения на уровне приложения:

extension UINavigationController {

  open override var preferredStatusBarStyle: UIStatusBarStyle {
      guard let index = tabBarController?.selectedIndex else { return .default }
      switch index {
      case 0, 1, 2: return .lightContent // set lightContent for tabs 0-2
      default: return .default // set dark for tab 3
      }
  }
}

Ответ 18

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

Установите View controller-based status bar внешний вид в НЕТ в plist, тогда в UIViewController viewDidAppear просто добавлена ​​следующая строка

UIApplication.shared.setStatusBarStyle(UIStatusBarStyle.lightContent, animated: true)

Ответ 19

swift 3

если вид панели управления на основе контроллера = YES в Info.plist

то используйте это расширение для всех NavigationController

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

если нет UINavigationController и только UIViewController, то используйте код ниже:

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

Ответ 20

override var preferredStatusBarStyle: UIStatusBarStyle {
    return .lightContent
}

Это сработало для меня :) У меня есть Navigation Controller, встроенный в мои контроллеры представления со скрытой панелью навигации. Я хотел установить подсветку строки состояния в некоторых приложениях viewsin.

Ответ 21

Свифт 4+

для белого текста в строке состояния:

navigationController.navigationBar.barStyle = .blackTranslucent

Ответ 22

iOS 11.2

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.

    UINavigationBar.appearance().barStyle = .black

    return true
}

Ответ 23

Вы можете использовать свойство bool с именем "shouldStatusBarDark" для переключения цвета строки состояния. И вы также можете обновить его значение, чтобы изменить цвет строки состояния при прокрутке.

 var shouldStatusBarDark = false {
     didSet {
         setNeedsStatusBarAppearanceUpdate()
     }
 }

 override var preferredStatusBarStyle: UIStatusBarStyle {
     return shouldStatusBarDark ? .default : .lightContent
 }

 func scrollViewDidScroll(_ scrollView: UIScrollView) {
     let offSetY = scrollView.contentOffset.y
     if offSetY > 50 {
         UIView.animate(withDuration: 0.4, animations: {
             self.navView.alpha = 1
             self.shouldStatusBarDark = true
         })
     } else {
         UIView.animate(withDuration: 0.4, animations: {
             self.navView.alpha = 0
             self.shouldStatusBarDark = false
         })
     }
 }

Ответ 24

Большинство из этих ответов повторяются, но ни один из них не обращается к экрану запуска для меня при использовании темного фона.

Я обошел это с помощью следующего в моем info.plist который вывел в свет строку состояния.

<key>UIStatusBarStyle</key>
<string>UIStatusBarStyleLightContent</string>

Ответ 25

Если вы получаете предупреждение: Setter для 'statusBarStyle' устарел в iOS 9.0: Используйте - [UIViewController предпочитаемыйStatusBarStyle], затем для установки строки состояния на светлый или темный используйте следующий код:

//To set the status bar to white
self.navigationController?.navigationBar.barStyle = .black //or .blackTranslucent

//To set the status bar to black
self.navigationController?.navigationBar.barStyle = .default

Это не заставит ваш navBar изменить его, он просто указывает на стиль и, следовательно, соответственно меняет строку состояния.

NB. Вы должны убедиться, что вы установили в своем info.plist.

View controller-based status bar appearance to YES

Ответ 26

Если вы используете модальную презентацию, вам нужно установить:

viewController.modalPresentationCapturesStatusBarAppearance = true

Ответ 27

Я получал:

Переопределение var должно быть таким же доступным, как и его закрывающий тип

Что фиксируется добавлением public как:

override public var preferredStatusBarStyle: UIStatusBarStyle {
    get {
        return .lightContent
    }
}

В Swift3 iOS10.

Ответ 28

Для цели C просто добавьте эту строку в ваше приложение. МетодFinishLaunch

UIApplication.sharedApplication.statusBarStyle = UIStatusBarStyleLightContent;

Ответ 29

используя WebkitView

Swift 9.3 iOS 11.3

import UIKit
import WebKit

class ViewController: UIViewController, WKNavigationDelegate, WKUIDelegate {

    @IBOutlet weak var webView: WKWebView!
    var hideStatusBar = true

    override func loadView() {
        let webConfiguration = WKWebViewConfiguration()
        webView = WKWebView(frame: .zero, configuration: webConfiguration)
        webView.uiDelegate = self
        view = webView
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        self.setNeedsStatusBarAppearanceUpdate()
        let myURL = URL(string: "https://www.apple.com/")
        let myRequest = URLRequest(url: myURL!)
        UIApplication.shared.statusBarView?.backgroundColor = UIColor.red

         webView.load(myRequest)

    }
}

extension UIApplication {

    var statusBarView: UIView? {
        return value(forKey: "statusBar") as? UIView
    }

}

Ответ 30

Пожалуйста, добавьте следующую строку в ваш info.plist, тогда только вы можете достичь этого

"Просмотр строки состояния на основе контроллера = НЕТ"

И добавьте следующий фрагмент в ваш код и посмотрите результат

        UIApplication.shared.statusBarStyle = .lightContent
        UIApplication.shared.statusBarStyle = .default