Programming

iOSStatusBarStyle PreferredStatusBarStyle이 iOS 7에서 작동하지 않습니다

procodes 2020. 8. 4. 20:09
반응형

iOSStatusBarStyle PreferredStatusBarStyle이 iOS 7에서 작동하지 않습니다


iOS 7 용 Xcode 5로 빌드 된 iPhone 응용 프로그램 UIViewControllerBasedStatusBarAppearance=YES에서 info.plist설정 했으며 내 ViewController코드는 다음과 같습니다.

-(UIStatusBarStyle) preferredStatusBarStyle
{
    return UIStatusBarStyleLightContent;
}

그러나 상태 표시 줄은 여전히 ​​검은 색 바탕에 검은 색입니다.

내가 설정하여이 응용 프로그램 전반에 걸친 변화의 수를 알고 UIViewControllerBasedStatusBarAppearance=NOinfo.plist,하지만 난 사실에서이를 변경해야 viewController의해 viewController실행시 기준.


ViewController가 navigationController 내에 있으면 navigationController가 navigationBar.barStylestatusBarStyle을 결정 한다는 것을 발견했습니다 .

당신의 내비게이션 바의 설정 barStyle하려면 UIBarStyleBlackTranslucent(예. 흰색 상태 표시 줄의 텍스트를 줄 것이다 UIStatusBarStyleLightContent), 그리고 UIBarStyleDefault검은 상태 표시 줄의 텍스트를 줄 것이다 (예. UIStatusBarStyleDefault).

참고 이것은 당신이 완전히의를 통해 내비게이션 바의 색상을 변경하는 경우에도 적용 barTintColor.


자, 여기 속임수가 있습니다. "컨트롤러 기반 상태 표시 줄보기"키를 추가하고 값을 아니오로 설정해야합니다.

이것은이 키의 의미와 상반되는 값이지만 값을으로 설정하더라도 No상태 표시 줄의 모양과 뷰 컨트롤러에 표시 여부를 계속 변경할 수 있습니다. "예"처럼 작동하지만 "아니요"로 설정하십시오!

이제 상태 표시 줄을 흰색 또는 어두운 색으로 가져올 수 있습니다.


들어 preferredStatusBarStyle()내에서 작동하도록 UINavigationController하고 UITabBarController나는 현재 보이는 뷰 컨트롤러에서 선호하는 상태 표시 줄 스타일을 얻을 것이다 다음 코드를 추가합니다.

extension UITabBarController {
    public override func childViewControllerForStatusBarStyle() -> UIViewController? {
        return selectedViewController
    }
}

extension UINavigationController {
    public override func childViewControllerForStatusBarStyle() -> UIViewController? {
        return visibleViewController
    }
}

들어 스위프트 3 사람들은 방법이 있지만, 속성은 없습니다 :

extension UITabBarController {
    open override var childViewControllerForStatusBarStyle: UIViewController? {
        return selectedViewController
    }
}

extension UINavigationController {
    open override var childViewControllerForStatusBarStyle: UIViewController? {
        return visibleViewController
    }
}

스위프트 4.2 속성은 이름이 변경되었습니다 :

extension UITabBarController {
   open override var childForStatusBarStyle: UIViewController? {
        return selectedViewController
    }
}

extension UINavigationController {
   open override var childForStatusBarStyle: UIViewController? {
        return visibleViewController
    }
}

용법

class ViewController: UIViewController {

    // This will be called every time the ViewController appears
    // Works great for pushing & popping
    override var preferredStatusBarStyle: UIStatusBarStyle {
        return .lightContent
    }

}

나는 조금 늦게 올지 모르지만 다른 사람이 작동하고 검증 된 앱 전체 솔루션을 찾고있는 경우를 대비하여.

왜 이런 일이 발생하는지 설명하는 데 @mxcl이 정확합니다. 이를 수정하기 위해 UINavigationController의 preferredSatusBarStyle () 메소드를 대체하는 확장 (또는 obj-c의 카테고리)을 작성하기 만하면됩니다. 다음은 Swift의 예입니다.

extension UINavigationController {
    public override func preferredStatusBarStyle() -> UIStatusBarStyle {
        if let rootViewController = self.viewControllers.first {
            return rootViewController.preferredStatusBarStyle()
        }
        return super.preferredStatusBarStyle()
    }
}

이 코드는 단순히 첫 번째 뷰 컨트롤러 (루트 뷰 컨트롤러)를 추출하여 랩핑 해제합니다 (obj-c에서 nil이 아닌지 확인). 랩 해제가 성공하면 (nil이 아님) rootViewControllers preferredStatusBarStyle을 가져옵니다. 그렇지 않으면 기본값을 반환합니다.

이것이 필요한 사람에게 도움이되기를 바랍니다.


허용 된 답변에 대한 자세한 내용을 제공하려면 앱 대리인의 didFinishLaunchingWithOptions:방법 에 다음 줄을 넣으십시오 .

[UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent;

그런 다음 Info.plist에서 추가 View controller-based status bar appearance하고로 설정하십시오 NO.

전체 앱에 대해 동일한 상태 표시 줄 색상을 원할 경우 탐색 컨트롤러가 아닌이 방법을 사용해야한다고 생각합니다. UINavigationController, 또는 다른 UINavigationController곳에 다른 서브 클래스에 포함되지 않아도되는 화면이있을 수 있습니다 .

편집 : 코드를 입력하지 않고 할 수도 있습니다 : https : //.com/a/18732865/855680


viewDidLoad에서 이것을 작성하십시오.

[self setNeedsStatusBarAppearanceUpdate];

그냥 그렇게하면 작동합니다

당신이 이것을 시도 할 수 있습니까

Set UIViewControllerBasedStatusBarAppearance to NO.
Call [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];

내가 당신의 질문에서 당신이 이것과 같은 방법을 썼다는 것을 한 가지 더

 -(void)UIStatusBarStyle PreferredStatusBarStyle ()
        {
            return UIStatusBarStyle.LightContent;
        }

하지만 이런 식이어야합니다

-(UIStatusBarStyle)preferredStatusBarStyle{ 
    return UIStatusBarStyleLightContent; 
} 

Here is how I solved it. Usually the navigationController or tabBarController are the ones deciding the appearance of the status bar (hidden, color, etc).

So I ended up subclassing the navigation controller and overriding preferredStatusBarStyle. if the current visible ViewContorller implements StatusBarStyleHandler I ask for the value to be used as the style, if it doesn't I just return a default value.

The way you trigger an update of the status bar appearance is by calling setNeedsStatusBarAppearanceUpdate which triggers preferredStatusBarStyle again and updates UI according to what the method returns

public protocol StatusBarStyleHandler {
    var preferredStatusBarStyle: UIStatusBarStyle { get }
}

public class CustomNavigationCotnroller: UINavigationController {

    public override var preferredStatusBarStyle: UIStatusBarStyle {
        if let statusBarHandler = visibleViewController as? StatusBarStyleHandler {
            return statusBarHandler.preferredStatusBarStyle
        }

        return .default
    }
}

Then usage

public class SomeController: UIViewController, StatusBarStyleHandler {

    private var statusBarToggle = true

    // just a sample for toggling the status bar style each time method is called
    private func toggleStatusBarColor() {
        statusBarToggle = !statusBarToggle
        setNeedsStatusBarAppearanceUpdate()
    }

    public override var preferredStatusBarStyle: UIStatusBarStyle {
        return statusBarToggle ? .lightContent : .default
    }
}

Even with all the answers here i still didn't find the exact solution for me, but started with the answer from Daniel. What I ended up with was:

override var preferredStatusBarStyle: UIStatusBarStyle {
     return visibleViewController?.preferredStatusBarStyle ?? .lightContent
}

in navigation controllers (similar for tab, just selectedViewController). And then it will respect the:

override var preferredStatusBarStyle: UIStatusBarStyle {
     return .lightContent
}

In each view controller unless you set it otherwise. I dont need to call setNeedsStatusBarAppearanceUpdate() anywhere, it just updates when you arrive at each view controller.


1) One setting for whole project:

If available, remove UIViewControllerBasedStatusBarAppearance key-value pair from your info.plist, or set NO without removing it. If it's not available in your info.plist, do nothing. Default is NO for this property.

Add below code to your AppDelegate.m:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
}

2) Different settings for different View Controllers:

Add UIViewControllerBasedStatusBarAppearance key-value pair to your info.plist and set it to YES.

If your View Controller is not embed in to Navigation Controller. Let's say MyViewController. just add code below to your MyViewController.m file. If your View Controller is embed in to Navigation Controller, create a new Cocoa Touch Class and make it subclass of UINavigationController. Let's say MyNC. Select Navigation Controller View on your Storyboard, at right pane; Utilities -> Identity Inspector -> Custom Class -> Class, type "MyNC". After linking Storyboard View with your "MyNC" Cocoa Touch Class, add code below to your MyNC.m:

- (BOOL)prefersStatusBarHidden {
    return NO;
}

-(UIStatusBarStyle)preferredStatusBarStyle {
    return UIStatusBarStyleLightContent;
}

Swift 4.2

extension UITabBarController {
    open override var childForStatusBarStyle: UIViewController? {
        return selectedViewController
    }
}

extension UINavigationController {
    open override var childForStatusBarStyle: UIViewController? {
        return visibleViewController
    }
}

If in case you wanted to hide the statusBar during splashScreen but wanted to change the style to light content (StatusBarInitiallyHidden on Plist has to be NO to hide statusBar on splash), you can add this to appDelegate's didFinishLaunchingWithOptions method to change to lightContent.

[[UIApplication sharedApplication]setStatusBarHidden:NO withAnimation:UIStatusBarAnimationSlide];
[[UIApplication sharedApplication]setStatusBarStyle:UIStatusBarStyleLightContent];

swift example

in AppDelegate.swift

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {
    UIApplication.sharedApplication().statusBarStyle = UIStatusBarStyle.LightContent;

    return true
}

in info.plist set View controller-based status bar appearance: NO


If you're using NavigationController, you can subclass NavigationController so that it consults its child view controller

// MyCustomNavigationController

- (NSUInteger)supportedInterfaceOrientations {
    UIViewController *viewControllerToAsk = [self findChildVC];
    return [viewControllerToAsk supportedInterfaceOrientations];
}

- (BOOL)shouldAutorotate {
    UIViewController *viewControllerToAsk = [self findChildVC];
    return [viewControllerToAsk shouldAutorotate];
}

- (UIStatusBarStyle)preferredStatusBarStyle {
    UIViewController *viewControllerToAsk = [self findChildVC];
    return [viewControllerToAsk preferredStatusBarStyle];
}

- (UIViewController *)findChildVC {
    return self.viewControllers.firstObject;
}

You can set the status bar style. It will resembles the status bar like IOS 6 and below.
Paste this methods in your view controller

-(UIStatusBarStyle)preferredStatusBarStyle{
    return UIStatusBarStyleBlackOpaque;
}

and call this method from view did load like this

if([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0f)
    {
       [self setNeedsStatusBarAppearanceUpdate];
    }

I just want to add a note for a specific case I faced. I had another UIWindow in my app to display a chat face to be floating all over my app all the time. Doing this caused none of the solution above to work, and I am not really sure why! All what I have noticed is that my ViewController in the new UIWindow was the reason for that! And if I wanted to change the status bar style I have to do it in that view controller of the new UIWindow.

This note might help others who have a similar structure! So basically you can apply the solutions mentioned above in the ViewController of the new UIWindow.

Again this a specific case.

Thanks


For swift 3, in your UIViewController:

override var preferredStatusBarStyle : UIStatusBarStyle { return UIStatusBarStyle.lightContent }

참고URL : https://stackoverflow.com/questions/19108513/uistatusbarstyle-preferredstatusbarstyle-does-not-work-on-ios-7

반응형