Tôi đã theo chủ đề này để ghi đè -preferredStatusBarStyle
, nhưng nó không được gọi. Có bất kỳ tùy chọn mà tôi có thể thay đổi để kích hoạt nó? (Tôi đang sử dụng XIB trong dự án của mình.)
Tôi đã theo chủ đề này để ghi đè -preferredStatusBarStyle
, nhưng nó không được gọi. Có bất kỳ tùy chọn mà tôi có thể thay đổi để kích hoạt nó? (Tôi đang sử dụng XIB trong dự án của mình.)
Câu trả lời:
Tôi đã có cùng một vấn đề và nhận ra nó đã xảy ra bởi vì tôi không đặt trình điều khiển xem gốc trong cửa sổ ứng dụng của mình.
Cái UIViewController
mà tôi đã thực hiện preferredStatusBarStyle
được sử dụng trong một UITabBarController
, điều khiển sự xuất hiện của các khung nhìn trên màn hình.
Khi tôi đặt bộ điều khiển xem gốc để trỏ đến điều này UITabBarController
, các thay đổi trên thanh trạng thái bắt đầu hoạt động chính xác, như mong đợi (và preferredStatusBarStyle
phương thức đang được gọi).
(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
... // other view controller loading/setup code
self.window.rootViewController = rootTabBarController;
[self.window makeKeyAndVisible];
return YES;
}
Ngoài ra, bạn có thể gọi một trong các phương pháp sau, nếu phù hợp, trong mỗi bộ điều khiển chế độ xem của bạn, tùy thuộc vào màu nền của nó, thay vì phải sử dụng setNeedsStatusBarAppearanceUpdate
:
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
hoặc là
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];
Lưu ý rằng bạn cũng sẽ cần phải thiết lập UIViewControllerBasedStatusBarAppearance
để NO
trong file plist nếu bạn sử dụng phương pháp này.
setNeedsStatusBarAppearanceUpdate
- những nghi ngờ của tôi đã được xác nhận khi tôi thực hiện thay đổi này.
Đối với bất cứ ai sử dụng UINavestionControll:
Các UINavigationController
không mong về preferredStatusBarStyle
cuộc gọi đến bộ điều khiển xem con của nó. Thay vào đó, nó quản lý trạng thái của chính nó - như thường lệ, nó đang vẽ ở phía trên màn hình nơi thanh trạng thái sống và do đó phải chịu trách nhiệm cho nó. Do đó, việc triển khai preferredStatusBarStyle
các VC của bạn trong bộ điều khiển điều hướng sẽ không làm gì cả - chúng sẽ không bao giờ được gọi.
Bí quyết là những gì UINavigationController
sử dụng để quyết định trả lại cho UIStatusBarStyleDefault
hoặc UIStatusBarStyleLightContent
. Nó dựa trên cơ sở này UINavigationBar.barStyle
. Mặc định ( UIBarStyleDefault
) dẫn đến UIStatusBarStyleDefault
thanh trạng thái nền trước tối . Và UIBarStyleBlack
sẽ đưa ra một UIStatusBarStyleLightContent
thanh trạng thái.
TL; DR:
Nếu bạn muốn UIStatusBarStyleLightContent
trên UINavigationController
sử dụng:
self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
preferredStatusBarStyle
trên thực tế sẽ được gọi trên bộ điều khiển xem con nếu bạn ẩn thanh điều hướng (được đặt navigationBarHidden
thành YES
), chính xác khi thích hợp.
[[UINavigationBar appearance] setBarStyle:UIBarStyleBlack]
navigationBarHidden
thiết lập YES
sẽ thực sự preferredStatusBarStyle
được gọi và một cảnh báo cho những người có thể vấp ngã về điều này: nó hoạt động với navigationBarHidden
, nhưng không phải với navigationBar.hidden
!
Vì vậy, tôi thực sự đã thêm một danh mục vào UINavestionControll nhưng đã sử dụng các phương thức:
-(UIViewController *)childViewControllerForStatusBarStyle;
-(UIViewController *)childViewControllerForStatusBarHidden;
và có những cái trả về UIViewControll hiện tại. Điều đó cho phép bộ điều khiển chế độ xem hiển thị hiện tại đặt kiểu / mức độ hiển thị ưa thích của riêng nó.
Đây là một đoạn mã hoàn chỉnh cho nó:
Trong Swift:
extension UINavigationController {
public override func childViewControllerForStatusBarHidden() -> UIViewController? {
return self.topViewController
}
public override func childViewControllerForStatusBarStyle() -> UIViewController? {
return self.topViewController
}
}
Trong Mục tiêu-C:
@interface UINavigationController (StatusBarStyle)
@end
@implementation UINavigationController (StatusBarStyle)
-(UIViewController *)childViewControllerForStatusBarStyle {
return self.topViewController;
}
-(UIViewController *)childViewControllerForStatusBarHidden {
return self.topViewController;
}
@end
Và để có biện pháp tốt, đây là cách nó được triển khai trong UIViewControll:
Trong Swift
override public func preferredStatusBarStyle() -> UIStatusBarStyle {
return .LightContent
}
override func prefersStatusBarHidden() -> Bool {
return false
}
Trong Mục tiêu-C
-(UIStatusBarStyle)preferredStatusBarStyle {
return UIStatusBarStyleLightContent; // your own style
}
- (BOOL)prefersStatusBarHidden {
return NO; // your own visibility code
}
Cuối cùng, hãy đảm bảo rằng ứng dụng của bạn không có "Giao diện thanh trạng thái dựa trên bộ điều khiển" được đặt thành NO. Xóa dòng đó hoặc đặt thành CÓ (mà tôi tin là mặc định cho iOS 7?)
return self.topViewController;
hoạt động đối với tôi, nhưng return self.visibleViewController;
- không phải
super
theo phương thức này và bạn thực sự muốn thay đổi hành vi của tất cả các bộ điều khiển loại này
Đối với bất cứ ai vẫn đang vật lộn với điều này, phần mở rộng đơn giản này trong swift sẽ khắc phục vấn đề cho bạn.
extension UINavigationController {
override open var childForStatusBarStyle: UIViewController? {
return self.topViewController
}
}
Ứng dụng của tôi sử dụng cả ba: UINavigationController
, UISplitViewController
, UITabBarController
, do đó những vẻ tất cả để giành quyền kiểm soát trên thanh trạng thái và sẽ gây ra preferedStatusBarStyle
để không bị gọi là cho con cái của họ. Để ghi đè hành vi này, bạn có thể tạo một phần mở rộng như phần còn lại của các câu trả lời đã đề cập. Đây là một phần mở rộng cho cả ba, trong Swift 4. Chúc Apple hiểu rõ hơn về loại công cụ này.
extension UINavigationController {
open override var childViewControllerForStatusBarStyle: UIViewController? {
return self.topViewController
}
open override var childViewControllerForStatusBarHidden: UIViewController? {
return self.topViewController
}
}
extension UITabBarController {
open override var childViewControllerForStatusBarStyle: UIViewController? {
return self.childViewControllers.first
}
open override var childViewControllerForStatusBarHidden: UIViewController? {
return self.childViewControllers.first
}
}
extension UISplitViewController {
open override var childViewControllerForStatusBarStyle: UIViewController? {
return self.childViewControllers.first
}
open override var childViewControllerForStatusBarHidden: UIViewController? {
return self.childViewControllers.first
}
}
Chỉnh sửa: Cập nhật các thay đổi API Swift 4.2
extension UINavigationController {
open override var childForStatusBarStyle: UIViewController? {
return self.topViewController
}
open override var childForStatusBarHidden: UIViewController? {
return self.topViewController
}
}
extension UITabBarController {
open override var childForStatusBarStyle: UIViewController? {
return self.children.first
}
open override var childForStatusBarHidden: UIViewController? {
return self.children.first
}
}
extension UISplitViewController {
open override var childForStatusBarStyle: UIViewController? {
return self.children.first
}
open override var childForStatusBarHidden: UIViewController? {
return self.children.first
}
}
Câu trả lời của Tyson là chính xác để thay đổi màu thanh trạng thái thành màu trắng UINavigationController
.
Nếu bất cứ ai muốn thực hiện cùng một kết quả bằng cách viết mã vào AppDelegate
thì sử dụng mã bên dưới và viết mã bên trongAppDelegate's
didFinishLaunchingWithOptions
phương thức.
Và đừng quên để thiết lập UIViewControllerBasedStatusBarAppearance
đểYES
trong file plist, nếu không thay đổi sẽ không phản ánh.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// status bar appearance code
[[UINavigationBar appearance] setBarStyle:UIBarStyleBlack];
return YES;
}
Trên một UINavestionControll, preferredStatusBarStyle
không được gọi vì nó topViewController
được ưa thích hơn self
. Vì vậy, để được preferredStatusBarStyle
gọi trên UINavestionControll, bạn cần thay đổichildViewControllerForStatusBarStyle
.
Ghi đè Trình điều khiển UINavestion của bạn trong lớp của bạn:
class MyRootNavigationController: UINavigationController {
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
override var childViewControllerForStatusBarStyle: UIViewController? {
return nil
}
}
Để làm điều đó cho tất cả UINavestionControll, bạn có thể ghi đè lên một tiện ích mở rộng (cảnh báo: nó ảnh hưởng đến UIDocumentPickerViewControll, UIImagePickerContoder, v.v.), nhưng có lẽ bạn không nên làm điều đó theo tài liệu Swift :
extension UINavigationController {
open override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
open override var childViewControllerForStatusBarStyle: UIViewController? {
return nil
}
}
Ngoài câu trả lời của serenn, nếu bạn đang trình bày bộ điều khiển xem với modalPresentationStyle
(ví dụ .overCurrentContext
), bạn cũng nên gọi nó trên bộ điều khiển xem mới được trình bày:
presentedViewController.modalPresentationCapturesStatusBarAppearance = true
Đừng quên ghi đè lên preferredStatusBarStyle
trong trình điều khiển xem được trình bày.
Một bổ sung cho câu trả lời của Hippo: nếu bạn đang sử dụng Trình điều khiển UINavestion, thì có lẽ tốt hơn là thêm một danh mục:
// UINavigationController+StatusBarStyle.h:
@interface UINavigationController (StatusBarStyle)
@end
// UINavigationController+StatusBarStyle.m:
@implementation UINavigationController (StatusBarStyle)
- (UIStatusBarStyle)preferredStatusBarStyle
{
//also you may add any fancy condition-based code here
return UIStatusBarStyleLightContent;
}
@end
Giải pháp đó có lẽ tốt hơn là chuyển sang hành vi sắp bị phản đối.
preferredStatusBarStyle
và thực hiện logic cụ thể của UINavestionControll . Ngay bây giờ logic này dựa trên navigationBar.barStyle
nhưng tôi có thể thấy các kiểm tra bổ sung được thêm vào (ví dụ: UISearchDisplayController
di chuyển để ẩn chế độ thanh điều hướng). Bằng cách ghi đè logic mặc định, bạn mất hết chức năng này và để mình mở cho những khoảnh khắc 'wtf' khó chịu trong tương lai. Xem câu trả lời của tôi ở trên để biết cách chính xác để làm điều này trong khi vẫn hỗ trợ hành vi điều khiển điều hướng được xây dựng.
Như đã đề cập trong câu trả lời được chọn , nguyên nhân gốc là để kiểm tra đối tượng điều khiển xem cửa sổ gốc của bạn.
childForStatusBarStyle
Sử dụng các tiện ích mở rộng sau, nó xử lý tất cả các tình huống trên -
extension UITabBarController {
open override var childForStatusBarStyle: UIViewController? {
return selectedViewController?.childForStatusBarStyle ?? selectedViewController
}
}
extension UINavigationController {
open override var childForStatusBarStyle: UIViewController? {
return topViewController?.childForStatusBarStyle ?? topViewController
}
}
extension AppRootViewController {
open override var preferredStatusBarStyle: UIStatusBarStyle {
return children.first { $0.childForStatusBarStyle != nil }?.childForStatusBarStyle?.preferredStatusBarStyle ?? .default
}
}
UIViewControllerBasedStatusBarAppearance
khóa info.plist
đúngTrong trường hợp bạn trình bày luồng mới theo phương thức, nó sẽ tách khỏi luồng kiểu thanh trạng thái hiện có. Vì vậy, giả sử bạn đang trình bày NewFlowUIViewController
và sau đó thêm điều hướng mới hoặc bộ điều khiển tabBar vào NewFlowUIViewController
, sau đó thêm phần mở rộng NewFlowUIViewController
cũng để quản lý kiểu thanh trạng thái của trình điều khiển xem thêm.
Trong trường hợp bạn đặt modalPftimeationStyle khác với fullScreen
khi trình bày phương thức, bạn phải đặt modalPresentationCapturesStatusBarAppearance
thành đúng để trình điều khiển xem được trình bày phải nhận được điều khiển xuất hiện trên thanh trạng thái.
UINavigationController
là một lớp con của UIViewController
(người biết)!
Do đó, khi trình bày bộ điều khiển chế độ xem được nhúng trong bộ điều khiển điều hướng, bạn không thực sự trình bày bộ điều khiển chế độ xem được nhúng; bạn đang trình bày các bộ điều khiển điều hướng! UINavigationController
, như là một lớp con của UIViewController
, kế thừa preferredStatusBarStyle
vàchildForStatusBarStyle
, mà bạn có thể đặt như mong muốn.
Bất kỳ phương pháp nào sau đây cũng nên hoạt động:
info.plist
, thêm thuộc tính sau:
UIUserInterfaceStyle
(còn gọi là "Kiểu giao diện người dùng")Ghi đè preferredStatusBarStyle
trongUINavigationController
preferredStatusBarStyle
( doc ) - Kiểu thanh trạng thái ưa thích cho trình điều khiển xemPhân lớp hoặc mở rộng UINavigationController
class MyNavigationController: UINavigationController {
override var preferredStatusBarStyle: UIStatusBarStyle {
.lightContent
}
}
HOẶC LÀ
extension UINavigationController {
open override var preferredStatusBarStyle: UIStatusBarStyle {
.lightContent
}
}
Ghi đè childForStatusBarStyle
trongUINavigationController
childForStatusBarStyle
( tài liệu ) - Được gọi khi hệ thống cần bộ điều khiển xem để sử dụng để xác định kiểu thanh trạng thái"Nếu trình điều khiển chế độ xem vùng chứa của bạn xuất phát kiểu thanh trạng thái từ một trong các trình điều khiển chế độ xem con của nó, [ghi đè thuộc tính này] và trả về trình điều khiển chế độ xem con đó. Nếu bạn trả về nil hoặc không ghi đè phương thức này, kiểu tự thanh trạng thái sẽ được sử dụng . Nếu giá trị trả về từ phương thức này thay đổi, hãy gọi phương thức setNeedStatusBarAppparentUpdate (). "
Phân lớp hoặc mở rộng UINavigationController
class MyNavigationController: UINavigationController {
override var childForStatusBarStyle: UIViewController? {
topViewController
}
}
HOẶC LÀ
extension UINavigationController {
open override var childForStatusBarStyle: UIViewController? {
topViewController
}
}
Bạn có thể trả về bất kỳ bộ điều khiển xem nào bạn muốn ở trên. Tôi đề nghị một trong những điều sau đây:
topViewController
(of UINavigationController
) ( doc ) - Bộ điều khiển xem ở đầu ngăn xếp điều hướngvisibleViewController
(of UINavigationController
) ( doc ) - Trình điều khiển chế độ xem được liên kết với chế độ xem hiện tại trong giao diện điều hướng (gợi ý: điều này có thể bao gồm "trình điều khiển chế độ xem được trình bày một cách vừa phải trên đầu bộ điều khiển điều hướng")Lưu ý: Nếu bạn quyết định phân lớp UINavigationController
, hãy nhớ áp dụng lớp đó cho bộ điều khiển điều hướng của bạn thông qua trình kiểm tra danh tính trong IB.
PS Mã của tôi sử dụng cú pháp Swift 5.1
Câu trả lời của @ serenn ở trên vẫn là một câu trả lời tuyệt vời cho trường hợp của UINavestionControllers. Tuy nhiên, đối với swift 3, các hàm childViewControll đã được thay đổi thành vars
. Vì vậy, UINavigationController
mã mở rộng phải là:
override open var childViewControllerForStatusBarStyle: UIViewController? {
return topViewController
}
override open var childViewControllerForStatusBarHidden: UIViewController? {
return topViewController
}
Và sau đó trong trình điều khiển chế độ xem nên ra lệnh kiểu thanh trạng thái:
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
Nếu viewContoder của bạn nằm dưới UINavestionControll.
Phân lớp UINavestionControll và thêm
override var preferredStatusBarStyle: UIStatusBarStyle {
return topViewController?.preferredStatusBarStyle ?? .default
}
ViewContoder preferredStatusBarStyle
sẽ được gọi.
UIStatusBarStyle trong iOS 7
Thanh trạng thái trong iOS 7 là trong suốt, chế độ xem phía sau hiển thị thông qua.
Phong cách của thanh trạng thái đề cập đến sự xuất hiện của nội dung của nó. Trong iOS 7, nội dung trên thanh trạng thái là dark ( UIStatusBarStyleDefault
) hoặc light ( UIStatusBarStyleLightContent
). Cả hai UIStatusBarStyleBlackTranslucent
và UIStatusBarStyleBlackOpaque
không được dùng trong iOS 7.0. Sử dụngUIStatusBarStyleLightContent
thay thế.
Cách thay đổi UIStatusBarStyle
Nếu bên dưới thanh trạng thái là thanh điều hướng, kiểu thanh trạng thái sẽ được điều chỉnh để phù hợp với kiểu thanh điều hướng (UINavigationBar.barStyle
):
Cụ thể, nếu kiểu thanh điều hướng là UIBarStyleDefault, kiểu thanh trạng thái sẽ là UIStatusBarStyleDefault
; nếu kiểu thanh điều hướng là UIBarStyleBlack
, kiểu thanh trạng thái sẽ làUIStatusBarStyleLightContent
.
Nếu không có thanh điều hướng bên dưới thanh trạng thái, kiểu thanh trạng thái có thể được điều khiển và thay đổi bởi một bộ điều khiển xem riêng lẻ trong khi ứng dụng chạy.
- [UIViewController preferredStatusBarStyle]
là một phương thức mới được thêm vào trong iOS 7. Nó có thể được ghi đè để trả về kiểu thanh trạng thái ưa thích:
- (UIStatusBarStyle)preferredStatusBarStyle
{
return UIStatusBarStyleLightContent;
}
Nếu kiểu thanh trạng thái nên được điều khiển bởi trình điều khiển xem con thay vì tự, ghi đè -[UIViewController childViewControllerForStatusBarStyle]
để trả về bộ điều khiển xem con đó.
Nếu bạn muốn từ chối hành vi này và đặt kiểu thanh trạng thái bằng cách sử dụng -[UIApplication statusBarStyle]
phương thức, hãy thêm UIViewControllerBasedStatusBarAppearance
khóa vào Info.plist
tệp của ứng dụng và cung cấp cho nó giá trị KHÔNG.
Nếu bất cứ ai đang sử dụng Bộ điều khiển Điều hướng và muốn tất cả các bộ điều khiển điều hướng của họ có kiểu màu đen, bạn có thể viết một phần mở rộng cho UINavestionContoder như thế này trong Swift 3 và nó sẽ áp dụng cho tất cả các bộ điều khiển điều hướng (thay vì gán nó cho một bộ điều khiển tại thời gian).
extension UINavigationController {
override open func viewDidLoad() {
super.viewDidLoad()
self.navigationBar.barStyle = UIBarStyle.black
}
}
Trong Swift cho bất kỳ loại UIViewControll nào:
Trong AppDelegate
bộ của bạn :
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
window!.rootViewController = myRootController
return true
}
myRootController
có thể là bất kỳ loại nào UIViewController
, ví dụ UITabBarController
hoặc UINavigationController
.
Sau đó, ghi đè bộ điều khiển gốc như thế này:
class RootController: UIViewController {
override func preferredStatusBarStyle() -> UIStatusBarStyle {
return .LightContent
}
}
Điều này sẽ thay đổi giao diện của thanh trạng thái trong toàn bộ ứng dụng của bạn, bởi vì bộ điều khiển gốc chỉ chịu trách nhiệm cho sự xuất hiện của thanh trạng thái.
Hãy nhớ đặt thuộc tính View controller-based status bar appearance
thành CÓ trong của bạn Info.plist
để làm cho công việc này (là mặc định).
Hầu hết các câu trả lời không bao gồm triển khai tốt childViewControllerForStatusBarStyle
phương pháp cho UINavigationController
. Theo kinh nghiệm của tôi, bạn nên xử lý các trường hợp như khi trình điều khiển xem trong suốt được trình bày trên bộ điều khiển điều hướng. Trong những trường hợp này, bạn nên chuyển điều khiển cho bộ điều khiển phương thức ( visibleViewController
), nhưng không phải khi nó biến mất.
override var childViewControllerForStatusBarStyle: UIViewController? {
var childViewController = visibleViewController
if let controller = childViewController, controller.isBeingDismissed {
childViewController = topViewController
}
return childViewController?.childViewControllerForStatusBarStyle ?? childViewController
}
Đối với iOS 13.4, preferredStatusBarStyle
phương thức trong UINavigationController
danh mục sẽ không được gọi, swizzling dường như là tùy chọn duy nhất mà không cần sử dụng lớp con.
Thí dụ:
Tiêu đề danh mục:
@interface UINavigationController (StatusBarStyle)
+ (void)setUseLightStatusBarStyle;
@end
Thực hiện:
#import "UINavigationController+StatusBarStyle.h"
#import <objc/runtime.h>
@implementation UINavigationController (StatusBarStyle)
void (^swizzle)(Class, SEL, SEL) = ^(Class c, SEL orig, SEL new){
Method origMethod = class_getInstanceMethod(c, orig);
Method newMethod = class_getInstanceMethod(c, new);
if(class_addMethod(c, orig, method_getImplementation(newMethod), method_getTypeEncoding(newMethod)))
class_replaceMethod(c, new, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));
else
method_exchangeImplementations(origMethod, newMethod);
};
+ (void)setUseLightStatusBarStyle {
swizzle(self.class, @selector(preferredStatusBarStyle), @selector(_light_preferredStatusBarStyle));
}
- (UIStatusBarStyle)_light_preferredStatusBarStyle {
return UIStatusBarStyleLightContent;
}
@end
Sử dụng trong AppDelegate.h:
#import "UINavigationController+StatusBarStyle.h"
[UINavigationController setUseLightStatusBarStyle];
Đây là phương pháp của tôi để giải quyết điều này.
Xác định một giao thức được gọi là AGViewControllAppparent .
AGViewControllAppurdy.h
#import <Foundation/Foundation.h>
@protocol AGViewControllerAppearance <NSObject>
@optional
- (BOOL)showsStatusBar;
- (BOOL)animatesStatusBarVisibility;
- (UIStatusBarStyle)preferredStatusBarStyle;
- (UIStatusBarAnimation)prefferedStatusBarAnimation;
@end
Xác định một danh mục trên UIViewControll gọi là Nâng cấp .
UIViewControll + Nâng cấp.h
#import <UIKit/UIKit.h>
@interface UIViewController (Upgrade)
//
// Replacements
//
- (void)upgradedViewWillAppear:(BOOL)animated;
@end
UIViewControll + Nâng cấp.m
#import "UIViewController+Upgrade.h"
#import <objc/runtime.h>
#import "AGViewControllerAppearance.h" // This is the appearance protocol
@implementation UIViewController (Upgrade)
+ (void)load
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wselector"
Method viewWillAppear = class_getInstanceMethod(self, @selector(viewWillAppear:));
#pragma clang diagnostic pop
Method upgradedViewWillAppear = class_getInstanceMethod(self, @selector(upgradedViewWillAppear:));
method_exchangeImplementations(viewWillAppear, upgradedViewWillAppear);
}
#pragma mark - Implementation
- (void)upgradedViewWillAppear:(BOOL)animated
{
//
// Call the original message (it may be a little confusing that we're
// calling the 'same' method, but we're actually calling the original one :) )
//
[self upgradedViewWillAppear:animated];
//
// Implementation
//
if ([self conformsToProtocol:@protocol(AGViewControllerAppearance)])
{
UIViewController <AGViewControllerAppearance> *viewControllerConformingToAppearance =
(UIViewController <AGViewControllerAppearance> *)self;
//
// Status bar
//
if ([viewControllerConformingToAppearance respondsToSelector:@selector(preferredStatusBarStyle)])
{
BOOL shouldAnimate = YES;
if ([viewControllerConformingToAppearance respondsToSelector:@selector(animatesStatusBarVisibility)])
{
shouldAnimate = [viewControllerConformingToAppearance animatesStatusBarVisibility];
}
[[UIApplication sharedApplication] setStatusBarStyle:[viewControllerConformingToAppearance preferredStatusBarStyle]
animated:shouldAnimate];
}
if ([viewControllerConformingToAppearance respondsToSelector:@selector(showsStatusBar)])
{
UIStatusBarAnimation animation = UIStatusBarAnimationSlide;
if ([viewControllerConformingToAppearance respondsToSelector:@selector(prefferedStatusBarAnimation)])
{
animation = [viewControllerConformingToAppearance prefferedStatusBarAnimation];
}
[[UIApplication sharedApplication] setStatusBarHidden:(! [viewControllerConformingToAppearance showsStatusBar])
withAnimation:animation];
}
}
}
@end
Bây giờ, đã đến lúc nói rằng bộ điều khiển xem của bạn đang triển khai AGViewControllAppurdy giao thức .
Thí dụ:
@interface XYSampleViewController () <AGViewControllerAppearance>
... the rest of the interface
@end
Tất nhiên, bạn có thể triển khai phần còn lại của các phương thức ( showsStatusBar , animatesStatusBarVisibility , prefferedStatusBarAnimation ) từ giao thức và UIViewControll + Nâng cấp sẽ thực hiện tùy chỉnh phù hợp dựa trên các giá trị được cung cấp bởi chúng.
Lưu ý rằng khi sử dụng self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
giải pháp
hãy chắc chắn đi đến phần chính của bạn và đặt "Xem giao diện thanh trạng thái dựa trên bộ điều khiển" thành CÓ. Nếu nó KHÔNG nó sẽ không hoạt động.
Kể từ Xcode 11.4, ghi đè preferredStatusBarStyle
tính trong tiện ích mở rộng UINavestionControll không còn hoạt động nữa vì nó sẽ không được gọi.
Thiết lập barStyle
của navigationBar
để .black
công trình thực sự nhưng điều này sẽ bổ sung thêm các tác dụng phụ không mong muốn nếu bạn thêm subviews đến Navigationbar có thể có bệnh cảnh khác nhau cho chế độ ánh sáng và bóng tối. Bởi vì bằng cách đặt barStyle
thành màu đen, userInterfaceStyle
chế độ xem được nhúng trong navigationBar sau đó sẽ luôn có userInterfaceStyle.dark
bất kểuserInterfaceStyle
ứng dụng nào.
Giải pháp thích hợp tôi đưa ra là bằng cách thêm một lớp con UINavigationController
và ghi đè lên preferredStatusBarStyle
đó. Nếu sau đó bạn sử dụng UINavestionControll tùy chỉnh này cho tất cả các chế độ xem của bạn, bạn sẽ ở bên lưu.
NavigationContoder hoặc TabBarControll là những cái cần cung cấp kiểu. Đây là cách tôi giải quyết: https://stackoverflow.com/a/39072526/242769