UIStatusBarStyle не меняется

Я работаю над быстрым приложением и хочу изменить UIStatusBarStyle в соответствии с темой приложения (есть 2 варианта - светлая и темная тема). Я установил View controller-based status bar appearance на NO в info.plist, а в UIViewController я попытался установить его на основе текущей темы следующим образом:

override var preferredStatusBarStyle: UIStatusBarStyle {
    return Theme.current.statusBarStyle
}


protocol ThemeProtocol { 
    // Status Bar
    var statusBarStyle: UIStatusBarStyle { get } 
}

class Theme {
    static var current: ThemeProtocol = LightTheme()
}

class LightTheme: ThemeProtocol {
    // Status Bar 
    var statusBarStyle: UIStatusBarStyle = .default

}

class DarkTheme: ThemeProtocol {
    // Status Bar 
    var statusBarStyle: UIStatusBarStyle = .lightContent

}

Никакого результата на самом деле. Я попытался проверить это, вернув только: return .lightContent, но это также не изменило строку состояния.

Что я делаю не так?

ОБНОВЛЕНИЕ:

Итак, это то, что я пытаюсь сделать, и это не работает.

    fileprivate func applyTheme() {

    statusBarStyle = UserDefaults.standard.bool(forKey: SelectedThemeKey) ? .default : .lightContent
    self.setNeedsStatusBarAppearanceUpdate()

}

override var preferredStatusBarStyle: UIStatusBarStyle {
    return statusBarStyle
}

И это не работает. Несмотря на изменение темы, строка состояния всегда остается в стиле по умолчанию. applyTheme() вызывается в viewDidLoad() и viewWillAppear()


person Dani    schedule 11.08.2018    source источник


Ответы (3)


Вам нужно вызывать этот метод после любого изменения

setNeedsStatusBarAppearanceUpdate()

//

class ViewController: UIViewController {

    var current = UIStatusBarStyle.default

    @IBAction func changeClicked(_ sender: Any) {
        current = current == .default ? .lightContent : .default
        self.setNeedsStatusBarAppearanceUpdate()
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }
    override  var preferredStatusBarStyle: UIStatusBarStyle {
        return current
    }

}

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

person Sh_Khan    schedule 11.08.2018
comment
Я пытаюсь воспроизвести то, что вы поделились, и по какой-то причине это не работает. Не могли бы вы взглянуть на обновленный код в моем посте выше? - person Dani; 11.08.2018
comment
это создается с настройками проекта по умолчанию, поэтому откатывайтесь ко всем изменениям, которые вы сделали внутри info.plist - person Sh_Khan; 11.08.2018
comment
Да, я только что удалил View controller-based status bar appearance из info.plist, и теперь все работает. Благодарю вас! - person Dani; 11.08.2018
comment
вы устанавливаете значение «Нет», когда хотите полностью скрыть его - person Sh_Khan; 11.08.2018
comment
Что это значит, когда вы пишете current = current == .default ? .lightContent: .по умолчанию? .... Я понимаю, что current == .default означает, что значение current равно .default, но я пытаюсь понять остальное. - person bobcat; 13.09.2018
comment
@bhealth это эквивалентно if---else ищите тернарный оператор в swift - person Sh_Khan; 13.09.2018

Во-первых, ваш код не имеет смысла. Ты говоришь

Я установил внешний вид строки состояния на основе контроллера View в NO в info.plist, а в UIViewController я попытался установить его.

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

Во-вторых, имейте в виду, что ваш контроллер представления не имеет права голоса во внешнем виде строки состояния, если только он не является контроллером представления верхнего уровня (или контроллер представления верхнего уровня преднамеренно подчиняется ему). Например, если ваш контроллер представления находится внутри контроллера навигации, его statusBarStyle совершенно не имеет значения.

person matt    schedule 11.08.2018
comment
На самом деле я читал, что вам нужно установить View controller-based status bar appearance на NO, чтобы это работало, и для меня это не имело смысла, но это очень неправильно. Спасибо, что указали на это. И для дополнительной информации - person Dani; 11.08.2018

Первый

если вы пытаетесь заменить StatusBarStyle на UIApplication.shared.statusBarStyle = .default, вам следует установить View controller-based status bar appearance на NO.

таким образом, вам нужно везде самостоятельно контролировать UIApplication.shared.statusBarStyle; например viewWillAppear / viewWillDisappear.

но этот метод устарел после iOS 9.

Теперь я предлагаю вам изучить новый способ:

установите View controller-based status bar appearance на YES и

переопределите preferredStatusBarStyle UIViewController, чтобы справиться с этим.

override var preferredStatusBarStyle: UIStatusBarStyle {
    return .default
}

но он все еще не работает, почему?

в вашем случае я предполагаю, что UIViewController является одним из viewControllers из UINavigationController.

если вы использовали UINavigationController, вы должны переопределить preferredStatusBarStyle в UINavigationController.

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

Просто переопределите childForStatusBarStyle в UINavigationController вот так

override var childForStatusBarStyle: UIViewController? {
    return topViewController
}

затем переопределите preferredStatusBarStyle в UIViewController, которое вы хотите изменить.

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

extension UINavigationController {
    override open var childForStatusBarStyle: UIViewController? {
        return topViewController
    }
}
person 張家齊    schedule 10.09.2018