Як приховати рядок стану в додатку Swift iOS?


201

Я хотів би видалити рядок стану у верхній частині екрана.

Це не працює:

func application
(application: UIApplication,
didFinishLaunchingWithOptions launchOptions: NSDictionary?)
-> Bool
{
        application.statusBarHidden = true
        return true
}

Я також спробував:

func application
(application: UIApplication,
didFinishLaunchingWithOptions launchOptions: NSDictionary?)
-> Bool
{
    self.window = UIWindow(frame: UIScreen.mainScreen().bounds)

    var controller = UIViewController()
    application.statusBarHidden = true
    controller.setNeedsStatusBarAppearanceUpdate()

    var view = UIView(frame: CGRectMake(0, 0, 320, 568))
    view.backgroundColor = UIColor.redColor()
    controller.view = view

    var label = UILabel(frame: CGRectMake(0, 0, 200, 21))
    label.center = CGPointMake(160, 284)
    label.textAlignment = NSTextAlignment.Center
    label.text = "Hello World"
    controller.view.addSubview(label)

    self.window!.rootViewController = controller
    self.window!.makeKeyAndVisible()
    return true
}

Відповіді:


449

Ви дійсно повинні реалізувати на своїх контролерах перегляду переваги prefersStatusBarHidden:

Swift 3 і пізніші

override var prefersStatusBarHidden: Bool {
    return true
}

4
Я думаю, що Джей має намір приховати рядок стану для повного застосування. Ось чому він написав функцію приховування у програмі didFinishLaunchingWithOptions. Як приховати рядок стану для повного додатка?
Сатьям

@Satyam має хороший момент, було б непогано видалити це протягом усієї програми. Чи існує підхід до реалізації цього шляхом успадкування? Або через розширення протоколу?
Дан Болье

3
@DanBeaulieu Я думаю, що спадщина була б чудовим рішенням. Створіть підклас UIViewController, у якому прихований рядок встановлено на істинне, а потім зробіть усі ваші підкласи успадкованими від цього. Іншим підходом може бути використання Swizzling
crisGriega

1
Код Swift 3 не працював, дивіться: stackoverflow.com/a/38902285/129202
Jonny

1
У цьому способі є помилка: коли ви хочете виконати вираз, ваш батьківський погляд поточного контролера перегляду падає приблизно на 20 пікс
iman kazemayni

99
  1. Перейдіть у файл Info.plist
  2. Наведіть курсор на один із цих рядків і відобразяться кнопки (+) та (-).
  3. Натисніть кнопку плюс, щоб додати нову клавішу Введіть початок з великої літери V, і автоматично першим вибором буде перегляд панелі стану на основі контролера.
  4. Додайте це як КЛЮЧ.
  5. Встановіть VALUE на "NO"
  6. Перейти до вас AppDelegate.swift
  7. Додайте код всередину методу

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject:AnyObject]?) -> Bool {
        application.statusBarHidden = true
        return true
    }

Зроблено! Запустіть додаток і більше немає рядка стану!


1
Спочатку я подумав, що це рішення справно працює, але потім я помітив, що він викликає помилку, яку мені потрібно налагодити за допомогою CG_CONTEXT_SHOW_BACKTRACE. Зняв це з додаванням "Перегляд зовнішнього вигляду рядка стану на основі контролера"
Шон


1
Працював для тренажера iOS 10.1. Дякую, @nycdanie.
Ієронім

7
Окрім встановлення параметра "Перегляд зовнішнього вигляду рядка стану на основі контролера", також додайте "Рядок стану спочатку приховано", встановлений на "ТАК". Тоді вам не потрібно додавати код у контролер перегляду, і рядок стану буде приховано у всій програмі. Xcode 8.1, Swift 3.0.1, iOS 10
tylerSF

1
@tylerSF Чудово працює! Ви повинні додати це як відповідь :)
Pétur Ingi Egilsson

72

Швидкий 3

В Info.plistустановленому View controller-based status bar appearanceдляNO

І дзвоніть UIApplication.shared.isStatusBarHidden = true


1
Якщо це встановлено так, це єдиний спосіб, який він буде працювати.
farzadshbfn

@farzadshbfn це неправильно. Як я вже згадував і перевірений мною, він працює з булевим НІ.
Codetard

43

Якщо ви хочете приховати і повернути рядок стану при натисканні кнопки , а під час подання та відхилення розсувного меню , спливаючих вікон тощо, ви можете скористатися цим методом:

Щоб приховати рядок стану: -

UIApplication.shared.keyWindow?.windowLevel = UIWindowLevelStatusBar

Щоб повернути рядок стану: -

UIApplication.shared.keyWindow?.windowLevel = UIWindowLevelNormal 

Це більше хак. Я б не хотів втручатися у таке вікно ... особливо якщо рішення вже існує. Я б закликав розробників змінити prefersStatusBarHiddenвластивість, як те, про що вже говорилося.
Стівен Пол

2
це можна використовувати, якщо ми хочемо миттєво сховати та повернути рядок стану .. у моєму додатку, коли меню слайдера надходить з лівого боку, я повинен приховати рядок стану. і коли меню зникає, нам потрібно повернути рядок стану, як-от у додатку для iOS gmail .. тому в таких сценаріях ми можемо використовувати це.
Вінсент Джой

3
Це хак, і я б не потикатися з ним, але він робить роботу на даний момент. Так, як ви всі кажете. Проблема prefersStatusBarHiddenполягає в тому, що погляди, прив’язані до рядка стану за допомогою обмежень, а також панелі навігації, будуть рухатися навколо невдало, якщо ви вмикаєте / вимикаєте рядок стану за допомогою prefersStatusBarHidden . На даний момент тільки ця відповідь, здається, обходить це.
Джоні

Цілком погоджуюся з @Jonny, мені це рішення теж не подобається, але, як він сказав, переосмислення prefersStatusBarHiddenбуде зіпсувати ваше обмеження. Поки це робить свою роботу. Однак я використовую маленьку обгортку, щоб не використовувати одиночних
кнопок

34

якщо ви віддаєте перевагу візуальному підходу, а не кодуванню, використовуйте цей метод: у вашому info.plist

введіть тут опис зображення просто додати View controller-based status bar appearanceдоNO

і Status bar is initially hiddenякYES


Це канонічна відповідь у 2018 році
ChrisH

28
 override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(true);
    navigationController?.navigationBar.hidden = true // for navigation bar hide
    UIApplication.sharedApplication().statusBarHidden=true; // for status bar hide
}

28

Оновлення для iOS 10 / Swift 3.0

Більше не функція, тепер властивість ...

override var prefersStatusBarHidden: Bool {
    return true
}

Чи знаєте ви, як налаштувати це протягом усього додатка, наразі я мушу вводити це в кожний перегляд Контролер
Вільям Т.

Спробуйте меню "Знайти", а потім "Знайти та замінити в проекті"? Можливо? Але той проклятий додатковий брекет з вкладеними вийшов ... хммм .... не знаю. Гарне питання!
atlwx

prefersStatusBarHidden ніколи не називали
Bagusflyer

6
Вам не потрібно, get { }якщо у вас немає set, просто напишітьreturn true
Даніель



12

Тож проблема тут насправді не має нічого спільного із Swift, а лише з тим, як обробляється зовнішній вигляд рядка стану, як на iOS 7.

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

prefersStatusBarHidden, preferredStatusBarStyle, preferredStatusBarAnimation,

У вашому випадку ви б просто здійснити prefersStatusBarHiddenта повернути true.

Іншим способом було б контролювати появу рядка стану на рівні програми. Здається, це те, що ви насправді намагаєтесь зробити (встановивши application.statusBarHidden).

Для того, щоб зробити цю роботу, вам потрібно відкрити Info.plistфайл свого додатка і додати ключ UIViewControllerBasedStatusBarAppearanceі надати йому значення NO.


1
Я думаю, ти маєш на увазі повернення справжнього для prefersStatusBarHidden. НЕМАЄ належить до ObjC і в будь-якому випадку є неправильним значенням bool.
HenryRootTwo

@HenryRootTwo не у .plist файлах. Там ми все ще використовуємо ТАК / НІ
Alex Сала

8

Я насправді сам це зрозумів. Я додам своє рішення як інший варіант.

extension UIViewController {
    func prefersStatusBarHidden() -> Bool {
        return true
    }
}

Приємний підхід до того, щоб зберегти чистоту та модульність
Roger Fernandez Guri

2
Я не можу цього здійснити. Можливо, це тому, що зараз я використовую Swift 1.2. Я отримую помилку: "Метод" prefersStatusBarHidden () "із селектором Objective-C" prefersStatusBarHidden "конфліктує з попередньою декларацією з тим же селектором Objective-C". Я також додав ключове слово переосмислення на початку, але все одно отримую ту ж помилку.
Андрій

Вам потрібно додати це до кожного перегляду?
Шон

Не працює в Swift 2, показує помилку, як пояснив @Andrej вище.
Nagendra Rao

4

Гаразд, це стане для мене проблемою, оскільки iOS 9 не підтримує жодного вище методу, про який люди вже згадували, наприклад, UIApplication.sharedApplication().statusBarHidden = true або

UIApplication.sharedApplication().setStatusBarHidden(true, withAnimation: UIStatusBarAnimation.None)

і

override func prefersStatusBarHidden() -> Bool {
     return true
}

працює, але не забезпечує програмованого рішення, де я можу змінити умову. ( statusBarHidden = trueі statusBarHidden = falseяк ми це робили раніше).

Вирішення цього безумства:

Додавши, prefersStatusBarHidden()як подобається нижче, ви можете програмно контролювати приховування та показ рядка стану, не додаючи UIViewControllerBasedStatusBarAppearanceналаштування до свого списку info.plist :

var showStatusBar = true

override func prefersStatusBarHidden() -> Bool {
     if showStatusBar {
         return false
     }
     return true
}

private func showStatusBar(enabled: Bool) {
    showStatusBar = enabled
    prefersStatusBarHidden()
}

то використовуйте його так у всьому коді:

//Hide Status Bar
showStatusBar(false)

АБО

//Show Status Bar
showStatusBar(true)

1
Чи prefersStatusBarHiddenмає сенс дзвінок? Я думаю, ви маєте self.setNeedsStatusBarAppearanceUpdate()на увазі після showStatusBarприсвоєння
Лев

Це насправді безумство, чи не так? Що це за жалісний API, і так довго існує. Такі речі роблять розробки iOS часом неймовірними.
Womble

@Womble, так, і це може стати досить складним. Сподіваємось, у Swift 3.0 є краща бібліотека та підтримується, оскільки при першому погляді на це, це змінить всю партію від швидкої 2.3 ... зламаної речі.
CodeOverRide

Замість виклику перевагStatusBarHidden у своєму методі ви можете зателефонувати setNeedsStatusBarAppearanceUpdate
Оскар

4

Просто додамо, що при переосмисленні prefersStatusBarHiddenметоду або змінної, View controller-based status bar appearanceв Info.plist повинен бути ТАК, інакше переопределення не матиме ефекту



3

У моєму випадку я шукав рядок стану, щоб сховати / показати на вимогу; а не просто тоді, коли вигляд завантажується або зникає.

стрімкий 3.x

//show status bar initially
var showStatusBar = true

//set the parameters
override var prefersStatusBarHidden: Bool {

    if showStatusBar == true {

        //does not prefer status bar hidden
        print("does not prefer status bar hidden")
        return false

    } else {

        //does prefer status bar hidden
        print("does prefer status bar hidden")
    return true

    }
}

//ex: hide status bar and call parameter function again whenever you want
        showStatusBar = false
        setNeedsStatusBarAppearanceUpdate()

3

Swift 5: у контролері головного перегляду або в головному контролері навігації, якщо у вас є

    override var preferredStatusBarStyle: UIStatusBarStyle {
        return .lightContent
    }

    override var prefersStatusBarHidden: Bool {
        return false
    }

І "Перегляд вигляду рядка стану на основі контролера" в плісті повинно бути ТАК, інакше наведений вище код не буде називатися.

Якщо ви хочете приховати рядок стану під час запуску програми, "Рядок стану спочатку приховано" у списку повинно бути ТАК. Це може запобігти викривленню зображення запуску при появі додаткової синьої смуги у верхній частині екрана.


2

Рішення, яке працює для мене; якщо ви хочете приховати рядок стану на певному контролері перегляду під час завантаження:

import UIKit

class ViewController: UIViewController {

private var hideStatusBar: Bool = false

override var prefersStatusBarHidden: Bool {
    return hideStatusBar
}

override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation {
    return UIStatusBarAnimation.slide
}

override func viewDidLoad() {
    super.viewDidLoad()

    view.backgroundcolor = .white
    hideStatusBar = true

    UIView.animate(withDuration: 0.3) {
        self.setNeedsStatusBarAppearanceUpdate()
    }
}

Увага: якщо ви встановите в своєму інформаційному списку клавішу " Перегляд зовнішнього вигляду рядка стану на основі контролера " значення " НІ ", код вище не працює. Вам слід встановити ключ " ТАК " або видалити його з info.plist


Ви не можете змінити властивість hidStatusBar, оскільки це збережена властивість! однак ви можете просто вибрати інше ім’я, і ваша анімація працюватиме.
XcodeNOOB

2

У вашому проекті Загальні-> Інформація про розгортання-> Стиль рядка стану виберіть прапорець Сховати рядок стану Примітка: - вона приховує рядок стану протягом усієї програми


1
Це працює для мене (ios 12), де відповіді на плісти не відповідають.
тридцять

2

Для Swift 4+ спробуйте наступний код (тестований на Swift 4.0, 4.1 - IOS 10, 11):

override var prefersStatusBarHidden: Bool { return true }

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    // call this func to force preferredStatusBarStyle to be read again.
    setNeedsStatusBarAppearanceUpdate()
}

2

Швидкий 5+

У моєму випадку мені потрібно оновити рядок стану, прихований на основі деяких умов.

Через це я створю базовий контролер, BaseViewControllerякий містить нову властивість hideStatusBar.

Інші контролери перегляду є підкласом цього базового контролера. Нарешті, коли я хочу оновити поведінку рядка стану, мені потрібно лише змінити це hideStatusBarзначення.

class BaseViewController: UIViewController {

    var hideStatusBar: Bool = false {
        didSet {
            setNeedsStatusBarAppearanceUpdate()
        }
    }

    override var prefersStatusBarHidden: Bool {
           return hideStatusBar
    }
}

Як використовувати

final class ViewController: BaseViewController, UIScrollViewDelegate {
    let scrollView = UIScrollView()

    ...

    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        UIView.animate(withDuration: 0.3) {
            if scrollView.contentOffset.y > 100 {
                self.hideStatusBar = true
            } else {
                self.hideStatusBar = false
            }
        }
    }
}

Демо

Ось демонстрація, яку я використовую, UIView.animate(...)щоб зробити перехід більш плавним.

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


1

Я використовую Xcode 8.1 (8B62) з ціллю розгортання, встановленою на 10.1, і мені не пощастило з переліченими вище варіантами заміщення. Однак перевірка параметра "Сховати рядок стану" в "Інформація про розгортання" зробила для мене хитрість.

Проект> Загальне

Я сподіваюся, що це допомагає.


1

Якщо ви презентуєте контролер перегляду модально, спробуйте

viewController.hidesBottomBarWhenPushed = true
viewController.modalPresentationCapturesStatusBarAppearance = true

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

4
Відповідаючи на запитання, будь ласка, поясніть свою відповідь, фрагмент коду не є правильною відповіддю.
LazerBanana

0

Ви можете використовувати цей код у своєму ViewController Class scope

open override var prefersStatusBarHidden: Bool { return true }

Дякую за відповідь, чи хочете ви детальніше розробити. Де саме він повинен додати рядок коду і чому це буде працювати? Дивіться розділ Як написати гарну відповідь .
9953-div-37

0

У проекті-> Загальні-> Інформація про розгортання

Стиль панелі стану: -

щойно позначено Сховати смужку стану (iOS 10)


0

Швидкий 4

//MARK:- Show Status Bar
UIApplication.shared.isStatusBarHidden = false

//MARK:- Hide Status Bar
UIApplication.shared.isStatusBarHidden = true

нормально, зараз у мене немає ніяких ios 12, у мене є 11.4, коли його оновлення я також виправлю, також якщо у вас є teamviewer, я прийду і виправлю його на вашій системі
Shakeel Ahmed

вона застаріла
В’ячаслав Герчичев

0

Оновлено для iOS 13 та Swift 5

Якщо жоден з перерахованих вище відповідей не працює для вас. Перевірте свій список, щоб побачити, чи є у вас такий:

"Переглянути зовнішній вигляд рядка стану на основі контролера"

Якщо так, то обов'язково встановіть це ТАК !!!!!

Тоді працює наступний код.

override var prefersStatusBarHidden: Bool {
    return true
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.