Как скрыть строку состояния в приложении 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
}
сойка
источник
Возможный дубликат Как скрыть строку состояния в iOS?
Джейк Часан

Ответы:

450

Вы действительно должны реализовать prefersStatusBarHidden на своих контроллерах представления:

Свифт 3 и позже

override var prefersStatusBarHidden: Bool {
    return true
}
drewag
источник
4
Я думаю, что намерение Джея состоит в том, чтобы скрыть строку состояния для полного приложения. Вот почему он написал бы функцию скрытия в didFinishLaunchingWithOptions приложения. Как скрыть строку состояния для полного приложения?
Satyam
@Satyam имеет хорошую точку зрения, было бы неплохо удалить это по всему приложению. Есть ли подход для реализации этого через наследование? Или через расширение протокола?
Дэн Болье,
3
@ DanBeaulieu Я думаю, что наследование было бы отличным решением. Создайте подкласс UIViewController, где bar hidden установлен в true, а затем сделайте так, чтобы все ваши подклассы наследовали от него. Другим подходом может быть использование Swizzling
кризис Griega
1
Код Swift 3 не работал, см .: stackoverflow.com/a/38902285/129202
Джонни
1
В этом методе есть ошибка: когда вы хотите выполнить переход, ваш родительский вид текущего viewcontroller падает примерно на 20 пикселей
iman kazemayni
99
  1. Перейти к файлу Info.plist
  2. Наведите указатель мыши на одну из этих строк, и появятся кнопки (+) и (-).
  3. Нажмите кнопку «плюс», чтобы добавить новый ключ. Введите начальный с заглавной буквы V, и автоматически будет выбран первый вариант - просмотреть внешний вид строки состояния на основе контроллера.
  4. Добавьте это как КЛЮЧ.
  5. Установите ЗНАЧЕНИЕ на «НЕТ»
  6. Перейти к вам AppDelegate.swift
  7. Добавьте код внутри метода

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

СДЕЛАНО! Запустите ваше приложение и больше нет строки состояния!

nycdanie
источник
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
Если установлено значение yes, это единственный способ, которым это будет работать.
farzadshbfn
@farzadshbfn это не правильно. Как уже упоминалось и проверено мной, он работает с логическим NO.
Кодетард
43

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

Чтобы скрыть строку состояния: -

UIApplication.shared.keyWindow?.windowLevel = UIWindowLevelStatusBar

Чтобы вернуть строку состояния: -

UIApplication.shared.keyWindow?.windowLevel = UIWindowLevelNormal 
Винсент Джой
источник
Это больше взломать. Я бы не хотел вмешиваться в это окно ... особенно, если решение уже существует. Я бы посоветовал разработчикам переопределить prefersStatusBarHiddenсвойство, как уже упоминалось.
Стивен Пол
2
это можно использовать, если мы хотим на мгновение скрыть и вернуть строку состояния ... в моем приложении, когда меню слайдера появляется с левой стороны, мне нужно скрыть строку состояния. и когда меню исчезает, мы должны вернуть строку состояния, как в iOS-приложении gmail ... так что в таких случаях мы можем использовать это.
Винсент Джой
3
Это взлом, и я бы не стал вмешиваться, но это делает работу на данный момент. Вроде как вы все говорите. Проблема в prefersStatusBarHiddenтом, что представления, привязанные к строке состояния с помощью ограничений, а также панели навигации, будут плохо перемещаться, если вы включаете / выключаете строку состояния с помощью prefersStatusBarHidden . На данный момент только этот ответ, кажется, работает вокруг этого.
Джонни
Полностью согласен с @Jonny, мне тоже не нравится это решение, но, как он сказал, переопределение prefersStatusBarHiddenиспортит ваше ограничение. Пока это делает работу. Однако я использую небольшую обертку, чтобы избежать использования синглетонов, вы можете найти ее здесь
rgkobashi
34

если вы предпочитаете визуальный подход, а не кодирование, используйте этот метод: в вашем info.plist

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

и Status bar is initially hiddenкакYES

MiladiuM
источник
Это канонический ответ в 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
источник
Вы знаете, как установить это на протяжении всего приложения, в настоящее время я должен ввести это в каждый viewController
Уильям Т.
Попробуйте найти меню, затем найти и заменить в проекте? Может быть? Но это чертовски дополнительная скобка с вложенным get ... хммм ... не знаю. хороший вопрос!
atlwx
prefersStatusBarHidden никогда не вызывали
Bagusflyer
6
Вам не нужно, get { }если у вас нет set, просто напишитеreturn true
Даниэль
16

в Swift 3.x:

override func viewWillAppear(_ animated: Bool) {
    UIApplication.shared.isStatusBarHidden = true
}
Самира Экрами
источник
Это не рекомендуется в iOS 9.0
Georgios
16

Перейдите в ваш Info.plist и добавьте два ключа:

Перейдите в ваш Info.plist и добавьте два ключа:

janaz
источник
12

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

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

prefersStatusBarHidden, preferredStatusBarStyle, preferredStatusBarAnimation,

В вашем случае вы бы просто внедрили prefersStatusBarHiddenи вернулиtrue .

Другой способ - контролировать внешний вид строки состояния на уровне приложения. Похоже, это то, что вы на самом деле пытаетесь сделать (установив application.statusBarHidden).

Чтобы сделать это, вам нужно открыть Info.plistфайл вашего приложения, добавить ключ UIViewControllerBasedStatusBarAppearanceи присвоить ему значение NO.

Дима
источник
1
Я думаю, что вы имеете в виду вернуть true для prefersStatusBarHidden. NO принадлежит ObjC и в любом случае является неправильным значением bool.
HenryRootTwo
@HenryRootTwo не в файлах .plist. Там мы все еще используем ДА / НЕТ
Алекс Салом
8

Я на самом деле понял это сам. Я добавлю свое решение в качестве другого варианта.

extension UIViewController {
    func prefersStatusBarHidden() -> Bool {
        return true
    }
}
сойка
источник
Хороший подход к поддержанию чистоты и модульности
Роджер Фернандес Гури
2
Я не могу это реализовать. Может быть, это потому, что сейчас я использую Swift 1.2. Я получаю сообщение об ошибке: «Метод» prefersStatusBarHidden () с селектором Objective C «prefersStatusBarHidden» конфликтует с предыдущим объявлением с тем же селектором Objective C ». Я также добавил ключевое слово override в начале, но все равно получаю ту же ошибку.
Андрей
Вам нужно добавить это к каждому представлению?
Шон
Не работает в Swift 2, показывает ошибку, как объяснено @Andrej выше.
Нагендра Рао
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)
CodeOverRide
источник
1
Есть prefersStatusBarHiddenли смысл звонить? Я предполагаю, что вы имеете в виду self.setNeedsStatusBarAppearanceUpdate()после showStatusBarназначения
Лев
Это действительно безумие, не так ли? Какой это жалкий API, и так долго. Подобные вещи время от времени делают разработку iOS невероятно разочаровывающей.
Womble
@Womble, да, и это может быть довольно сложно. Надеюсь, Swift 3.0 имеет лучшую библиотеку и поддерживает, так как на первый взгляд, она сильно изменится с swift 2.3 ... ломая вещи.
CodeOverRide
Вместо вызова prefersStatusBarHidden из вашего метода вы можете вызвать setNeedsStatusBarAppearanceUpdate
Оскар
4

Просто добавьте, что при переопределении prefersStatusBarHiddenметода или переменной View controller-based status bar appearanceв Info.plist должно быть значение YES, иначе переопределение не будет иметь никакого эффекта

Huanyan
источник
4

в Swift 4.2 это свойство сейчас.

override var prefersStatusBarHidden: Bool {
    return true
}
Раванд Саид
источник
3

В моем случае я искал строку состояния, чтобы скрыть / показать по требованию; а не только когда представление загружается или исчезает.

Swift 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()
Felecia Genet
источник
3

Swift 5: в главном контроллере представления или главном навигационном контроллере, если у вас есть,

    override var preferredStatusBarStyle: UIStatusBarStyle {
        return .lightContent
    }

    override var prefersStatusBarHidden: Bool {
        return false
    }

И «Просмотр внешнего вида строки состояния на основе контроллера» в plist должен быть ДА, в противном случае приведенный выше код вызываться не будет.

Если вы хотите скрыть строку состояния при запуске приложения, «строка состояния изначально скрыта» в plist должно быть ДА. Это может предотвратить искажение начального изображения при отображении дополнительной синей полосы в верхней части экрана.

Сэм Сюй
источник
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()
    }
}

Внимание: если вы установили ключ « Просмотр внешнего вида строки состояния на контроллере » на « NO » в вашем info.plist, приведенный выше код не будет работать. Вы должны установить ключ на « ДА » или удалить его из info.plist

andre_hold
источник
Вы не можете переопределить свойство hideStatusBar, так как это сохраненное свойство! однако вы можете просто выбрать другое имя, и ваша анимация будет работать.
XcodeNOOB
2

В вашем проекте Общие-> Информация о развертывании-> Стиль строки состояния установите флажок Скрыть строку состояния. Примечание: - она ​​скрывает строку состояния во всем приложении.

Sweta Vani
источник
1
Это работает для меня (IOS 12), где plist ответов нет.
threeve
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()
}
Кодер ACJHP
источник
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(...)чтобы сделать переход более плавным.

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

nahung89
источник
1

Я использую Xcode 8.1 (8B62) с целью развертывания, установленной на 10.1, и мне не особо повезло с опциями переопределения, упомянутыми выше. Однако проверка опции «Скрыть строку состояния» в информации о развертывании сделала меня.

Проект> Общее

Надеюсь, это поможет.

danmerfeld
источник
1

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

viewController.hidesBottomBarWhenPushed = true
viewController.modalPresentationCapturesStatusBarAppearance = true
YannSteph
источник
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 }
Sajjad
источник
Спасибо за ответ, не могли бы вы рассказать подробнее? Где именно он должен добавить строку кода и почему это будет работать? Смотрите раздел Как написать хороший ответ .
9953-div-37
0

В вашем проекте-> Общие-> Информация о развертывании

Стиль строки состояния: -

только что пометил Скрыть строку состояния (iOS 10)

В.Д. Пурохит
источник
0

Swift 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
}
Леголас Ван
источник