Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/97.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios preferredStatusBarStyle不是';我没打电话_Ios_Ios7_Uikit_Uistatusbar - Fatal编程技术网

Ios preferredStatusBarStyle不是';我没打电话

Ios preferredStatusBarStyle不是';我没打电话,ios,ios7,uikit,uistatusbar,Ios,Ios7,Uikit,Uistatusbar,我随后重写了-preferredStatusBarStyle,但没有调用它。 是否有任何选项可以更改以启用它?(我在项目中使用XIB。)可能的根本原因 我也遇到了同样的问题,并且发现这是因为我没有在应用程序窗口中设置根视图控制器 我在其中实现了preferredStatusBarStyle的UIViewController用于UIAbbarController中,该控制器控制屏幕上视图的外观 当我将根视图控制器设置为指向此UITabBarController时,状态栏更改开始正常工作,正如预期的

我随后重写了
-preferredStatusBarStyle
,但没有调用它。 是否有任何选项可以更改以启用它?(我在项目中使用XIB。)

可能的根本原因 我也遇到了同样的问题,并且发现这是因为我没有在应用程序窗口中设置根视图控制器

我在其中实现了
preferredStatusBarStyle
UIViewController
用于
UIAbbarController
中,该控制器控制屏幕上视图的外观

当我将根视图控制器设置为指向此
UITabBarController
时,状态栏更改开始正常工作,正如预期的那样(并且调用了
preferredStatusBarStyle
方法)

替代方法(在iOS 9中已弃用) 或者,您可以在每个视图控制器中根据其背景颜色调用以下方法之一(视情况而定),而不必使用
setneedssStatusBarAppearanceUpdate

[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];


请注意,如果使用此方法,您还需要将plist文件中的
UIViewControllerBasedStatusBarAppearance
设置为
NO

Hippo回答的补充:如果您使用的是UINavigationController,则最好添加一个类别:

//  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

该解决方案可能比切换到即将被弃用的行为要好。

对于任何使用UINavigationController的人:

extension UINavigationController {

    public override func childViewControllerForStatusBarHidden() -> UIViewController? {
        return self.topViewController
    }

    public override func childViewControllerForStatusBarStyle() -> UIViewController? {
        return self.topViewController
    }
}
@interface UINavigationController (StatusBarStyle)

@end

@implementation UINavigationController (StatusBarStyle)

-(UIViewController *)childViewControllerForStatusBarStyle {
    return self.topViewController;
}

-(UIViewController *)childViewControllerForStatusBarHidden {
    return self.topViewController;
}

@end
UINavigationController
在调用其子视图控制器时不会转发
preferredStatusBarStyle
。相反,它管理自己的状态——正如它应该做的那样,它在屏幕顶部绘制状态栏所在的位置,因此应该对其负责。因此,在导航控制器内的VCs中实现
preferredStatusBarStyle
将不会起任何作用-它们永远不会被调用

诀窍在于
UINavigationController
使用什么来决定为
UIStatusBarStyleDefault
UIStatusBarStyleLightContent
返回什么。它基于其
UINavigationBar.barStyle
。默认设置(
UIBarStyleDefault
)会导致出现黑暗的前景
UIStatusBarStyleDefault
状态栏。而
UIBarStyleBlack
将给出一个
UIStatusBarStyleLightContent
状态栏

TL;医生:

extension UINavigationController {

    public override func childViewControllerForStatusBarHidden() -> UIViewController? {
        return self.topViewController
    }

    public override func childViewControllerForStatusBarStyle() -> UIViewController? {
        return self.topViewController
    }
}
@interface UINavigationController (StatusBarStyle)

@end

@implementation UINavigationController (StatusBarStyle)

-(UIViewController *)childViewControllerForStatusBarStyle {
    return self.topViewController;
}

-(UIViewController *)childViewControllerForStatusBarHidden {
    return self.topViewController;
}

@end
如果要在
UINavigationController
上使用
UIStatusBarStyleLightContent
,请使用:

self.navigationController.navigationBar.barStyle = UIBarStyleBlack;

因此,我实际上向UINavigationController添加了一个类别,但使用了以下方法:

-(UIViewController *)childViewControllerForStatusBarStyle;
-(UIViewController *)childViewControllerForStatusBarHidden;
并让它们返回当前可见的UIViewController。使当前可见视图控制器可以设置其自己的首选样式/可见性

下面是完整的代码片段:

在Swift中:

extension UINavigationController {

    public override func childViewControllerForStatusBarHidden() -> UIViewController? {
        return self.topViewController
    }

    public override func childViewControllerForStatusBarStyle() -> UIViewController? {
        return self.topViewController
    }
}
@interface UINavigationController (StatusBarStyle)

@end

@implementation UINavigationController (StatusBarStyle)

-(UIViewController *)childViewControllerForStatusBarStyle {
    return self.topViewController;
}

-(UIViewController *)childViewControllerForStatusBarHidden {
    return self.topViewController;
}

@end
在Objective-C中:

extension UINavigationController {

    public override func childViewControllerForStatusBarHidden() -> UIViewController? {
        return self.topViewController
    }

    public override func childViewControllerForStatusBarStyle() -> UIViewController? {
        return self.topViewController
    }
}
@interface UINavigationController (StatusBarStyle)

@end

@implementation UINavigationController (StatusBarStyle)

-(UIViewController *)childViewControllerForStatusBarStyle {
    return self.topViewController;
}

-(UIViewController *)childViewControllerForStatusBarHidden {
    return self.topViewController;
}

@end
下面是如何在UIViewController中实现的:

presentedViewController.modalPresentationCapturesStatusBarAppearance = true
在Swift中

override public func preferredStatusBarStyle() -> UIStatusBarStyle {
    return .LightContent
}

override func prefersStatusBarHidden() -> Bool {
    return false
}
在Objective-C中

-(UIStatusBarStyle)preferredStatusBarStyle {
    return UIStatusBarStyleLightContent; // your own style
}

- (BOOL)prefersStatusBarHidden {
    return NO; // your own visibility code
}

最后,确保您的应用程序plist没有将“基于视图控制器的状态栏外观”设置为否。请删除该行或将其设置为是(我认为这是iOS 7的默认设置?

以下是我解决此问题的方法

定义名为AGViewControllerAppearance的协议

AGViewControllerAppearance.h

#import <Foundation/Foundation.h>

@protocol AGViewControllerAppearance <NSObject>

@optional

- (BOOL)showsStatusBar;
- (BOOL)animatesStatusBarVisibility;
- (UIStatusBarStyle)preferredStatusBarStyle;
- (UIStatusBarAnimation)prefferedStatusBarAnimation;

@end
#import <UIKit/UIKit.h>

@interface UIViewController (Upgrade)

//
//  Replacements
//

- (void)upgradedViewWillAppear:(BOOL)animated;

@end
#导入
@协议AGViewControllerAppearance
@可选的
-(BOOL)showsStatusBar;
-(BOOL)animatessStatusBarVisibility;
-(UIStatusBarStyle)首选状态BarStyle;
-(UIStatusBarAnimation)首选状态Baranimation;
@结束
UIViewController上定义一个名为升级的类别

UIViewController+Upgrade.h

#import <Foundation/Foundation.h>

@protocol AGViewControllerAppearance <NSObject>

@optional

- (BOOL)showsStatusBar;
- (BOOL)animatesStatusBarVisibility;
- (UIStatusBarStyle)preferredStatusBarStyle;
- (UIStatusBarAnimation)prefferedStatusBarAnimation;

@end
#import <UIKit/UIKit.h>

@interface UIViewController (Upgrade)

//
//  Replacements
//

- (void)upgradedViewWillAppear:(BOOL)animated;

@end
#导入
@界面UIViewController(升级)
//
//替代品
//
-(void)upgradedViewWillAppear:(BOOL)动画;
@结束
UIViewController+Upgrade.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
#导入“UIViewController+Upgrade.h”
#进口
#导入“AGViewControllerAppearance.h”//这是外观协议
@实现UIViewController(升级)
+(空)荷载
{
#pragma-clang诊断推送
#pragma-clang诊断被忽略“-Wselector”
方法viewWillAspect=class_getInstanceMethod(self,@selector(viewWillAspect:);
#pragma-clang诊断流行语
方法upgradedViewWillAppear=class_getInstanceMethod(self,@selector(upgradedViewWillAppear:);
方法交换实施(视图将显示,升级视图将显示);
}
#pragma标记-实现
-(void)upgradedViewWillAppear:(BOOL)动画
{
//
//调用原始消息(可能有点困惑,我们正在
//调用“相同”方法,但实际上我们调用的是原始方法:))
//
[自升级视频:动画];
//
//实施
//
if([自确认协议:@协议(AGViewControllerAppearance)])
{
UIViewController*ViewControllerConforming to Appearance=
(UIViewController*)自身;
//
//状态栏
//
if([viewControllerConformingToAppearance respondsToSelector:@selector(preferredStatusBarStyle)])
{
BOOL shouldAnimate=是;
if([viewControllerConformingToAppearance respondsToSelector:@selector(AnimateStatusBarVisibility)])
{
shouldAnimate=[ViewControllerConforming to Appearance AnimagesStatusBarVisibility];
}
[[UIApplication sharedApplication]setStatusBarStyle:[ViewControllerConforming to Appearance preferredStatusBarStyle]
动画:应设置动画];
}
if([viewControllerConformingToAppearance respondsToSelector:@selector(showsStatusBar)])
{
UIStatusBarAnimation动画=UIStatusBarAnimation幻灯片;
如果([viewControllerConformingT
extension UINavigationController {
    open override var preferredStatusBarStyle: UIStatusBarStyle {
        return .lightContent
    }
    open override var childViewControllerForStatusBarStyle: UIViewController? {
        return nil
    }
}
override var preferredStatusBarStyle: UIStatusBarStyle {
    return .lightContent
 }
override open var childViewControllerForStatusBarStyle: UIViewController? {
  return topViewController
}

override open var childViewControllerForStatusBarHidden: UIViewController? {
  return topViewController
}
override var preferredStatusBarStyle: UIStatusBarStyle {
   return .lightContent
}
override var preferredStatusBarStyle: UIStatusBarStyle {
    return topViewController?.preferredStatusBarStyle ?? .default
}
extension UINavigationController {

    override open func viewDidLoad() {
        super.viewDidLoad()

        self.navigationBar.barStyle = UIBarStyle.black
    }

}
extension UINavigationController {
    override open var childForStatusBarStyle: UIViewController? {
        return self.topViewController
    }
}
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
    }
}
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
    }
}
presentedViewController.modalPresentationCapturesStatusBarAppearance = true
override var childViewControllerForStatusBarStyle: UIViewController? {
  var childViewController = visibleViewController
  if let controller = childViewController, controller.isBeingDismissed {
    childViewController = topViewController
  }
  return childViewController?.childViewControllerForStatusBarStyle ?? childViewController
}
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
    }
}
@interface UINavigationController (StatusBarStyle)
+ (void)setUseLightStatusBarStyle;
@end
#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
#import "UINavigationController+StatusBarStyle.h"

[UINavigationController setUseLightStatusBarStyle];