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

186

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

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

public func preferredStatusBarStyle() -> UIStatusBarStyle

Тем не менее, я обнаружил, что в Swift 3 он изменился на «Get ONLY varaiable».

public var preferredStatusBarStyle: UIStatusBarStyle { get } 

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

Willjay
источник
попробуйте этот var предпочитаемыйStatusBarStyle: UIStatusBarStyle = .lightContent
Anbu.Karthik

Ответы:

485

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

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

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

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

override var preferredStatusBarStyle: UIStatusBarStyle {     
      return .lightContent
}

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

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

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

Если ваше приложение будет поддерживать In вашего приложения 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
   }
}
Praveen
источник
3
Работает для меня. Забыл сначала вставить новую настройку в Info.plist.
Falsecrypt
1
@ LightMan uiapplication statusBarStyle не является устаревшим, я использовал это в iOS 11, и он работает.
Sushobhit
1
@Sushobhit setStatusBarStyle устарела в iOS 9, как используется в этом ответе. Но у вас все еще есть UIApplication.statusBarStyle как свойство только для чтения.
LightMan
1
Есть моменты, когда вы хотите иметь возможность установить его программно из-за цвета каждого вида.
Алехандро Кавазос
9
Вы также можете удалить строку в appDelegate.swift и перейти к Target -> General -> Deployment Info -> Style Bar Style -> Light
Robert Veringa
162

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

Эта статья оставлена ​​без изменений для тех, кто хочет понять логику различных подходов, которые присутствовали в течение последних нескольких лет. Между тем, начиная с Xcode 10, первый подход Swift 4.2 устарел и больше не поддерживается (т.е. не вступит в силу, если вы попытаетесь использовать его). Он по-прежнему используется для вашей информации, чтобы лучше понять обоснование 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")
        }
    }
}
Hexfire
источник
2
Если у вас есть строка состояния, вы также можете сделать это: statusBar.setValue (UIColor.red, forKey: "foregroundColor"); или использовать любой существующий ключ , чтобы установить любое свойство, которое доступно для UIStatusBar , но не для UIView
Mark
application.statusBarStyle = .lightContent. Этот подход обычно применяется, поскольку iOS9> Установщик для statusBarStyle устарел в iOS 9.0: Используйте - [UIViewController предпочитаемыйStatusBarStyle] ожидание, которое необходимо выполнить для UIViewController
toxicsun
Это единственное, что работает здесь при изменении цветовой темы приложения. Однако, кажется, после того, как это было установлено, вы всегда должны сбросить его при переключении контроллеров представления. С этого момента предпочтительный метод StatusBarStyle () игнорируется (даже при правильной настройке в info.plist).
нетоматический
2
Этот ответ более описательный по сравнению с другими.
ViruMax
2
Бонусное
130

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

 override var preferredStatusBarStyle: UIStatusBarStyle {
    return .lightContent
}

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

Abizern
источник
2
Это лучший подход, так как вы можете выбрать prefersStatusBarHiddenнекоторые из ваших взглядов. Если вы идете с UIApplication.shared.statusBarStyleвами, вы застряли с этим.
superarts.org
105

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
Gracu
источник
Я пытался только после добавления кода в делегат приложения, но настройка информационного списка была полезной для меня. Спасибо
Ахилеш Шарма
6
Сеттер для statusBarStyle устарел в iOS 9.0: Использование - [UIViewController предпочитаемыйStatusBarStyle]
Реймонд Хилл
33

Если вы хотите изменить statusBarцвет на белый, для всех представлений, содержащихся в a 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содержащихся него.

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

Мистер Xcoder
источник
Да, большое спасибо! У навигационного контроллера был маленький нюанс, который многие не учли!
Алексис Канделария
26

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

  • В файле info.list добавить строку: просмотреть внешний вид строки состояния контроллера и установить для нее значение YES

    var viewIsDark = Bool()
    
    func makeViewDark() {
    
        viewIsDark = true
        setNeedsStatusBarAppearanceUpdate()
    }
    
    func makeViewLight() {
    
        viewIsDark = false
        setNeedsStatusBarAppearanceUpdate()
    }
    
    override var preferredStatusBarStyle: UIStatusBarStyle {
    
        if viewIsDark {
            return .lightContent 
        } else {
            return .default 
        } 
    }
Алекс де Оливейра
источник
1
ИIf you call this method within an animation block, the changes are animated along with the rest of the animation block.
Александр Г
26

Xcode 10 или позже

Проверено в Swift 5

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

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

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

Не забудьте изменения info.plist

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

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

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

Вивек
источник
Для Xcode 10 / Swift5 это должен быть принятый ответ. Вы должны сделать ОБА шаги, чтобы это работало.
Джон Роби
Отлично. Спасибо! Я согласен, что это должен быть фактически принятый ответ.
DungeonDev
Это идеальный ответ 🤟🏻
nikhilgohil11
Это полностью работает и для Xcode 11 с Swift 5, спасибо
Луис Сантьяго
25

Вам необходимо добавить ниже ключ в вашем файле 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согласно требованию.

Химаншу Падия
источник
Хорошее решение, но считается ли это использованием частного API?
GoldenJoe
Работать хорошо, но как я могу изменить свой собственный цвет?
iSrinivasan27
@MohanSrinivasan вместо «UIColor.red» вы можете указать свой собственный цвет.
Химаншу падия
13

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

  1. Создайте новую запись в info.plist «Просмотр внешнего вида строки состояния на основе контроллера» и установите для нее значение «ДА».
  2. Перейдите к раскадровке и выберите контроллер навигации, который вы хотите изменить. Нажмите на панель навигации в разделе структуры документа раскадровки (левая панель на раскадровке).
  3. Перейдите на правую панель и щелкните раздел атрибутов.
  4. Под разделом панели навигации вы увидите стиль. Выберите стиль, который вы хотите (по умолчанию черный и черный для белого)

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

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

(Сделано с Xcode 8.3.3 во всем проекте Swift)

Брайан Норден
источник
«Просмотр внешнего вида строки состояния на основе контроллера» должен быть установлен на «НЕТ»
Willjay
2
Очень простой способ установить стиль строки состояния в соответствии с содержимым View Controller, что является правильным способом, а не просто установкой View controller-based status bar appearance = NOи использованием только светлого или темного стиля во всем приложении. Жаль, что этот «без кода» способ работает только в Navigation Controller, Apple следует рассмотреть возможность добавления другого поля для настройки этой опции в любом экземпляре View Controller.
aldoram5
12

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

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

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

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

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

2.1 ) Info.plist

Просмотр внешнего вида строки состояния на основе контроллера -> ДА

2.2 )

override var preferredStatusBarStyle : UIStatusBarStyle {
    return .lightContent
}

Objective-C (или реагировать нативно) меняется с App Delegate:

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

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

2) AppDelegate -> didFinishLaunchingWithOptions

[[UIApplication sharedApplication] setStatusBarHidden:NO animated:YES];
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDarkContent animated:YES];

Изменение строки состояния не работает при попытке сделать push (навигационные контроллеры), только при представлении модально viewcontrollers.

Doci
источник
8

Для первого шага вам нужно добавить строку с ключом: 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    
}
javimuu
источник
6

Swift 3

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

class YourViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

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

    }

}
youareawaitress
источник
6

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

Если вы хотите, чтобы запись .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

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

nCr78
источник
6

Чтобы добавить в великий asnwer @Krunal https://stackoverflow.com/a/49552326/4697535

В случае, если вы используете UINavigationController, не preferredStatusBarStyleбудет влиять на 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
      }
  }
}
Таль Сион
источник
5

Xcode 8.3.1, Swift 3.1

  1. Создайте новую запись в info.plist «Просмотр внешнего вида строки состояния на основе контроллера» и установите для нее значение «НЕТ».

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

application.statusBarStyle = .lightContent

joemalski
источник
5

Свифт 4+

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

navigationController.navigationBar.barStyle = .blackTranslucent
Альфи
источник
5

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

Если вы хотите установить статус стиль бар, уровень приложений , а затем установить UIViewControllerBasedStatusBarAppearanceна NOв вашем .plistфайле. И в вашем appdelegate> 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 в соответствии с уровнем настройки стиля строки состояния.

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

Krunal
источник
4

Swift 4.0 Пожалуйста, используйте этот код в "didFinishLaunchingWithOptions 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
}
Karthickkck
источник
4

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
}
Сатиш Бабария
источник
'blackOpaque' недоступен: используйте UIStatusBarStyleLightContent
Makalele
3

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

Установите View controller-based status barвнешний вид в NO в plist, затем в In UIViewController viewDidAppearпросто добавьте следующую строку

UIApplication.shared.setStatusBarStyle(UIStatusBarStyle.lightContent, animated: true)
Аншад Рашид
источник
setStatusBarStyle устарела в iOS 9.
Lastmboy
3

Свифт 3

если Просмотр строки состояния на основе контроллера = ДА в Info.plist

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

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

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

    extension UIViewController
    {
        override open var preferredStatusBarStyle: UIStatusBarStyle {
        return .lightContent
         }
     }
Датт Патель
источник
2
Не работает для меня Я получаю сообщения об ошибках «Свойство не переопределяет никакое свойство из своего суперкласса» и «Получатель для метода« привилегированныйСтатусБарСтиль »с помощью селектора Objective-C« ПредпочтительныйСтатусБарСтиль »конфликтует с предыдущим объявлением с тем же селектором Objective-C».
Тео
Спасибо за это, после 20 различных попыток и нескольких комбинаций предметов, чтобы попробовать это способ установить цвет строки состояния. Мне просто нужно было вспомнить вызов метода setNeedsStatusBarAppearanceUpdate (), когда я хотел изменить цвет при добавлении в ночном режиме, и черный на черном просто не работал.
Стюарт П.
3

Swift 5

Чтобы добавить более подробную информацию об ответе PRAVEEN по адресу https://stackoverflow.com/a/40066798/2082851 , я хотел бы представить свою реализацию. Он поддерживает гибкость настройки строки состояния каждого контроллера.

В общем, мы создадим свойство, BaseViewControllerкоторое будет обрабатывать это statusBarStyleсвойство во всех случаях. Когда вы создаете новый контроллер, сделайте его подклассом этого базового контроллера.

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

Реализация

class BaseViewController: UIViewController {

    var statusBarStyle: UIStatusBarStyle = .default {
        didSet {
            setNeedsStatusBarAppearanceUpdate()
        }
    }

    override var preferredStatusBarStyle: UIStatusBarStyle {
        return statusBarStyle
    }
}

демонстрация

class ViewController: BaseViewController, UIScrollViewDelegate {

    let scrollView = UIScrollView()
    ... 
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        UIView.animate(withDuration: 0.3) {
            if scrollView.contentOffset.y > 30 {
                self.statusBarStyle = .darkContent
            } else {
                self.statusBarStyle = .lightContent
            }
        }
    }
}

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

2. UINavigationController

Ведь UINavigationControllerэто особый случай, за которым вы можете следовать любым решениям:

Решение A: переопределить с отправкой сообщения

Так как UINavigationController является NSObjectи наследуется ObjectiveC, его методы есть, message dispatchи вы можете переопределить их.

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

Решение B: Создать UINavigationControllerподкласс

Если у вас уже есть кастом UINavigationController(который обычно должен контролировать больше требований), это лучшее решение для вас.

final class NavigationController: UINavigationController {
    override var preferredStatusBarStyle: UIStatusBarStyle {
        return topViewController?.preferredStatusBarStyle ?? super.preferredStatusBarStyle
    }
}
nahung89
источник
2

Вы можете использовать свойство 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
         })
     }
 }
Tiantong
источник
что такое свойство navView? Спасибо, что поделились своим решением
medskill
1
@medskill NavView - это просто мнемосхема навигации, добавленная программно.
Tiantong
2

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

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

<key>UIStatusBarStyle</key>
<string>UIStatusBarStyleLightContent</string>
CodeBender
источник
2

Если вы получаете предупреждение: 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
Ричард Хоуп
источник
2

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

viewController.modalPresentationCapturesStatusBarAppearance = true
RomanMisnikov
источник
1

В iOS 13 вы можете использовать .darkContent UIStatusBarStyleсвойство для отображения темной строки состояния

Юбер Фабисяк
источник
1

Если вы все еще не можете изменить стиль строки состояния базы на метод

override var preferredStatusBarStyle: UIStatusBarStyle {
    return .lightContent
}

Вы можете попробовать использовать этот метод:

override viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    navigationController?.navigationBar.barStyle = .black
}
Jin
источник
0

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

UIApplication.sharedApplication.statusBarStyle = UIStatusBarStyleLightContent;
Асфанд Шаббир
источник
3
Это не рекомендуется с iOS 9
MK_Dev
0

используя 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
    }

}
Оракул
источник
3
Свифт 9,3? Неправильный год, Марти
iOS iOS
Я рекомендую избегать использования частного API для примера "statusBar". Apple вносит изменения в API каждый раз! И когда Apple изменит этот API, ваше приложение может зависнуть, и оно больше не изменит строку состояния. Это заставит вас снова искать другое решение.
Doci