Я следил за этой веткой, чтобы переопределить -preferredStatusBarStyle
, но она не называется. Есть ли варианты, которые я могу изменить, чтобы включить его? (Я использую XIB в моем проекте.)
ios
ios7
uikit
uistatusbar
trgoofi
источник
источник
Ответы:
Возможная первопричина
У меня была та же проблема, и я понял, что это происходит, потому что я не настраивал контроллер корневого представления в моем окне приложения.
Объект,
UIViewController
в котором я реализовал,preferredStatusBarStyle
использовался в элементе управленияUITabBarController
, который контролировал отображение представлений на экране.Когда я установил корневой контроллер представления, чтобы указать на это
UITabBarController
, изменения строки состояния начали работать правильно, как и ожидалось (иpreferredStatusBarStyle
метод вызывался).Альтернативный метод (не рекомендуется в iOS 9)
Кроме того, вы можете вызвать один из следующих методов, в зависимости от ситуации, в каждом из ваших контроллеров представления, в зависимости от его цвета фона, вместо необходимости использовать
setNeedsStatusBarAppearanceUpdate
:или
Обратите внимание, что вам также нужно установить
UIViewControllerBasedStatusBarAppearance
значениеNO
в файле plist, если вы используете этот метод.источник
setNeedsStatusBarAppearanceUpdate
- мои подозрения подтвердились, когда я сделал это изменение.Для тех, кто использует UINavigationController:
UINavigationController
Не передает наpreferredStatusBarStyle
звонки на его взгляд ребенка контроллеров. Вместо этого он управляет своим собственным состоянием - как и положено, он рисует в верхней части экрана, где находится строка состояния, и поэтому должен нести за него ответственность. Поэтому реализацияpreferredStatusBarStyle
в ваших VC в контроллере nav ничего не даст - они никогда не будут вызываться.Хитрость в том, что
UINavigationController
использует, чтобы решить, за что возвращатьсяUIStatusBarStyleDefault
илиUIStatusBarStyleLightContent
. Это основано на егоUINavigationBar.barStyle
. По умолчанию (UIBarStyleDefault
) отображаетсяUIStatusBarStyleDefault
строка состояния темного переднего плана . ИUIBarStyleBlack
дастUIStatusBarStyleLightContent
статус бар.TL; DR:
Если вы хотите
UIStatusBarStyleLightContent
наUINavigationController
использование:источник
preferredStatusBarStyle
на самом деле вызов будет вызываться на дочернем контроллере представления, если вы спрячете панель навигации (установленаnavigationBarHidden
вYES
), точно так, как это необходимо.[[UINavigationBar appearance] setBarStyle:UIBarStyleBlack]
navigationBarHidden
set toYES
фактическиpreferredStatusBarStyle
вызвал, и предупреждение тем, кто может наткнуться на это: он работает сnavigationBarHidden
, но не сnavigationBar.hidden
!Поэтому я фактически добавил категорию в UINavigationController, но использовал методы:
и они возвращали текущий видимый UIViewController. Это позволяет текущему видимому контроллеру представления установить свой собственный предпочтительный стиль / видимость.
Вот полный фрагмент кода для этого:
В Свифте:
В Objective-C:
И для хорошей меры, вот как это реализовано тогда в UIViewController:
В Свифте
В Objective-C
Наконец, убедитесь , что ваше приложение PLIST это НЕ есть «View контроллера на основе строки состояния внешнего вида» набор для NO. Либо удалите эту строку, либо задайте для нее значение ДА (что, по моему мнению, является значением по умолчанию для iOS 7?)
источник
return self.topViewController;
работает для меня, ноreturn self.visibleViewController;
- нетsuper
этот метод, и вы действительно хотите изменить поведение всех контроллеров этого типаДля тех, кто все еще борется с этим, это простое расширение в swift должно решить проблему для вас.
источник
Мое приложение используется всего три:
UINavigationController
,UISplitViewController
,UITabBarController
, таким образом , они все , кажется, взять под свой контроль над строкой состояния и заставятpreferedStatusBarStyle
не называть свои ребенок. Чтобы изменить это поведение, вы можете создать расширение, как и в остальных ответах. Вот расширение для всех трех, в Swift 4. Хотелось бы, чтобы Apple была более ясна в этом отношении.Изменить: Обновление для изменений API Swift 4.2
источник
Ответ Тайсона является правильным для изменения цвета строки состояния на белый в
UINavigationController
.Если кто-то хочет добиться того же результата, написав код,
AppDelegate
используйте код ниже и напишите егоAppDelegate's
didFinishLaunchingWithOptions
метода.И не забудьте установить
UIViewControllerBasedStatusBarAppearance
значениеYES
в файле .plist, иначе изменение не отразится.Код
источник
На UINavigationController
preferredStatusBarStyle
не вызывается, потому что егоtopViewController
предпочитаютself
. Таким образом, чтобы вызватьpreferredStatusBarStyle
UINavigationController, вам нужно изменить егоchildViewControllerForStatusBarStyle
.Рекомендация
Переопределите свой UINavigationController в своем классе:
Не рекомендуемая альтернатива
Чтобы сделать это для всех UINavigationController, вы можете переопределить в расширении (предупреждение: это влияет на UIDocumentPickerViewController, UIImagePickerController и т. Д.), Но вам, вероятно, не следует делать это в соответствии с документацией Swift :
источник
В дополнение к ответу Серенна, если вы представляете контроллер представления с
modalPresentationStyle
(например.overCurrentContext
), вы должны также вызвать это на недавно представленном контроллере представления:Не забудьте также переопределить представленный
preferredStatusBarStyle
в представлении контроллер.источник
Дополнение к ответу Бегемота: если вы используете UINavigationController, то, вероятно, лучше добавить категорию:
Это решение, вероятно, лучше, чем переключение на поведение, которое скоро станет устаревшим.
источник
preferredStatusBarStyle
и выполняет специфическую логику UINavigationController. Прямо сейчас эта логика основана на,navigationBar.barStyle
но я вижу дополнительные проверки, добавляемые (например,UISearchDisplayController
чтобы скрыть режим navbar). Переопределяя логику по умолчанию, вы теряете всю эту функциональность и оставляете себя открытым для раздражающих моментов 'wtf' в будущем. Смотрите мой ответ выше для правильного способа сделать это, все еще поддерживая встроенное поведение контроллера навигации.Swift 4.2 и выше
Как уже упоминалось в выбранном ответе , основная причина заключается в проверке объекта контроллера корневого представления окна.
Возможные случаи вашей структуры потока
окна. Ваш корневой контроллер представления окна - это объект UIViewController, который дополнительно добавляет или удаляет контроллер навигации или tabController в зависимости от потока приложения.
Этот тип потока обычно используется, если ваше приложение имеет поток предварительной регистрации в стеке навигации без вкладок и поток последующей регистрации с вкладками и, возможно, каждая вкладка дополнительно содержит контроллер навигации.
Это поток, в котором контроллер корневого представления окна является tabBarController, возможно, каждая вкладка дополнительно содержит контроллер навигации.
Это поток, в котором контроллер корневого представления окна является навигационным контроллером.
Я не уверен, есть ли возможность добавить контроллер панели вкладок или новый контроллер навигации в существующий контроллер навигации. Но если есть такой случай, нам нужно передать управление стилем строки состояния следующему контейнеру. Итак, я добавил ту же проверку в расширении UINavigationController, чтобы найти
childForStatusBarStyle
Используйте следующие расширения, он обрабатывает все вышеперечисленные сценарии -
UIViewControllerBasedStatusBarAppearance
вводить,info.plist
как это верно по умолчаниюТочки для рассмотрения для более сложных потоков
Если вы представляете новый поток модально, он отсоединяется от существующего потока стилей строки состояния. Итак, предположим, что вы представляете,
NewFlowUIViewController
а затем добавляете новый контроллер навигации или tabBarNewFlowUIViewController
, а затем добавляете также расширениеNewFlowUIViewController
для управления стилем состояния дальнейшего просмотра контроллера.В случае, если вы устанавливаете modalPresentationStyle иначе, чем
fullScreen
при представлении модально, вы должны установитьmodalPresentationCapturesStatusBarAppearance
значение true, чтобы представленный контроллер представления должен был получить контроль внешнего вида строки состояния.источник
Решение для iOS 13
UINavigationController
это подклассUIViewController
(который знал 🙃)!Следовательно, при представлении контроллеров представления, встроенных в контроллеры навигации, вы на самом деле не представляете встроенные контроллеры представления; Вы представляете навигационные контроллеры!
UINavigationController
, как подклассUIViewController
, наследуетpreferredStatusBarStyle
иchildForStatusBarStyle
, который вы можете установить по своему усмотрению.Любой из следующих методов должен работать:
info.plist
, добавьте следующее свойство:UIUserInterfaceStyle
(он же «Стиль интерфейса пользователя»)Переопределить
preferredStatusBarStyle
внутриUINavigationController
preferredStatusBarStyle
( doc ) - предпочтительный стиль строки состояния для контроллера представленияПодкласс или расширение
UINavigationController
ИЛИ
Переопределить
childForStatusBarStyle
внутриUINavigationController
childForStatusBarStyle
( doc ) - вызывается, когда системе требуется контроллер представления, чтобы использовать для определения стиля строки состоянияПодкласс или расширение
UINavigationController
ИЛИ
Вы можете вернуть любой контроллер представления, который вы хотели бы выше. Я рекомендую одно из следующего:
topViewController
(ofUINavigationController
) ( doc ) - контроллер представления в верхней части стека навигацииvisibleViewController
(ofUINavigationController
) ( doc ) - Контроллер представления, связанный с текущим видимым представлением в интерфейсе навигации (подсказка: это может включать в себя «контроллер представления, который был представлен модально поверх самого контроллера навигации»)Примечание: если вы решили подкласс
UINavigationController
, не забудьте применить этот класс к контроллерам навигации с помощью инспектора идентификации в IB.PS Мой код использует синтаксис Swift 5.1 😎
источник
@ serenn в ответ выше еще один большой для случая UINavigationControllers. Однако для swift 3 функции childViewController были изменены на
vars
. Таким образом,UINavigationController
код расширения должен быть:И затем в контроллере представления, который должен диктовать стиль строки состояния:
источник
Если ваш viewController находится под UINavigationController.
Подкласс UINavigationController и добавить
ViewController
preferredStatusBarStyle
будет вызван.источник
UIStatusBarStyle в iOS 7
Строка состояния в iOS 7 прозрачная, вид за ней просвечивает.
Стиль строки состояния относится к внешнему виду ее содержимого. В iOS 7 содержимое строки состояния либо темное (
UIStatusBarStyleDefault
), либо светлое (UIStatusBarStyleLightContent
). ОбаUIStatusBarStyleBlackTranslucent
иUIStatusBarStyleBlackOpaque
устарели в iOS 7.0. ИспользуйтеUIStatusBarStyleLightContent
вместо этого.Как изменить
UIStatusBarStyle
Если под строкой состояния находится панель навигации, стиль строки состояния будет скорректирован в соответствии со стилем панели навигации (
UINavigationBar.barStyle
):В частности, если стиль панели навигации UIBarStyleDefault, стиль строки состояния будет
UIStatusBarStyleDefault
; если стиль панели навигации, стильUIBarStyleBlack
строки состояния будетUIStatusBarStyleLightContent
.Если под строкой состояния нет панели навигации, стиль строки состояния может контролироваться и изменяться отдельным контроллером представления во время работы приложения.
-
[UIViewController preferredStatusBarStyle]
это новый метод, добавленный в iOS 7. Его можно переопределить, чтобы вернуть предпочтительный стиль строки состояния:Если стиль строки состояния должен контролироваться дочерним контроллером представления вместо собственного, переопределите
-[UIViewController childViewControllerForStatusBarStyle]
чтобы вернуть этот дочерний контроллер представления.Если вы предпочитаете отказаться от этого поведения и установить стиль строки состояния с помощью
-[UIApplication statusBarStyle]
метода, добавьтеUIViewControllerBasedStatusBarAppearance
ключ вInfo.plist
файл приложения и присвойте ему значение NO.источник
Если кто-либо использует навигационный контроллер и хочет, чтобы все его навигационные контроллеры имели черный стиль, вы можете написать расширение для UINavigationController, подобное этому, в Swift 3, и оно будет применяться ко всем навигационным контроллерам (вместо назначения его одному контроллеру в время).
источник
В Swift для любого вида UIViewController:
В вашем
AppDelegate
наборе:myRootController
может быть любого типаUIViewController
, напримерUITabBarController
илиUINavigationController
.Затем переопределите этот корневой контроллер следующим образом:
Это изменит внешний вид строки состояния во всем приложении, поскольку корневой контроллер несет полную ответственность за внешний вид строки состояния.
Не забудьте установить для свойства
View controller-based status bar appearance
значение YES,Info.plist
чтобы это работало (по умолчанию).источник
Решение Swift 3 для iOS 10:
источник
Большинство ответов не включают в себя хорошую реализацию
childViewControllerForStatusBarStyle
метода дляUINavigationController
. Согласно моему опыту, вы должны обрабатывать такие случаи, когда контроллер прозрачного представления представлен поверх контроллера навигации. В этих случаях вы должны передать управление вашему модальному контроллеру (visibleViewController
), но не тогда, когда он исчезает.источник
В моем случае я случайно представил View / Navigation Controller как
UIModalPresentationStyle.overFullScreen
, что вызываетpreferredStatusBarStyle
не вызов. После переключения обратно наUIModalPresentationStyle.fullScreen
все работает.источник
Что касается iOS 13.4,
preferredStatusBarStyle
метод вUINavigationController
категории не будет вызываться, swizzling, кажется, является единственным вариантом без необходимости использования подкласса.Пример:
Заголовок категории:
Реализация:
Использование в AppDelegate.h:
источник
Вот мой метод решения этого.
Определите протокол с именем AGViewControllerAppearance .
AGViewControllerAppearance.h
Определите категорию в UIViewController, которая называется Upgrade .
UIViewController + Upgrade.h
UIViewController + Upgrade.m
Теперь пришло время сказать, что вы просматриваете контроллер реализует AGViewControllerAppearance протокол .
Пример:
Конечно, вы можете реализовать остальные методы ( showsStatusBar , animatesStatusBarVisibility , prefferedStatusBarAnimation ) из протокола и UIViewController + Обновление будет делать правильную настройку на основе значений , предоставляемых ими.
источник
Если кто-то столкнется с этой проблемой с UISearchController. Просто создайте новый подкласс UISearchController, а затем добавьте приведенный ниже код в этот класс:
источник
Обратите внимание, что при использовании
self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
решенияОбязательно зайдите в свой список и установите «Просмотр внешнего вида строки состояния на основе контроллера» на ДА. Если его нет, он не будет работать.
источник
Начиная с Xcode 11.4, переопределяя
preferredStatusBarStyle
свойства в расширении UINavigationController больше не работает, так как оно не будет вызываться.Установка
barStyle
изnavigationBar
к.black
работам , действительно , но это добавит нежелательные побочные эффекты , если добавить подвиды в Панель навигации , которая может иметь разный внешний вид для светлого и темного режима. Потому что, установив вbarStyle
черный цвет,userInterfaceStyle
представление, встроенное в навигационную панель, будет всегда иметьuserInterfaceStyle.dark
независимоuserInterfaceStyle
от приложения.Правильное решение, которое я придумаю, это добавление подкласса
UINavigationController
и переопределениеpreferredStatusBarStyle
там. Если вы затем используете этот пользовательский UINavigationController для всех ваших просмотров, вы будете на стороне сохранения.источник
NavigationController или TabBarController - те, которые должны обеспечить стиль. Вот как я решил: https://stackoverflow.com/a/39072526/242769
источник