深入理解iOS的状态栏

一、状态栏的隐藏

状态栏的隐藏主要有两种方法,下面来一起看看吧。

方法一:通过代码控制

@interface UIApplication(UIApplicationDeprecated)

// Setting statusBarHidden does nothing if your application is using the default UIViewController-based status bar system.
@property(readwrite, nonatomic,getter=isStatusBarHidden) BOOL statusBarHidden
NS_DEPRECATED_IOS(2_0, 9_0, "Use -[UIViewController prefersStatusBarHidden]") __TVOS_PROHIBITED;

- (void)setStatusBarHidden:(BOOL)hidden animated:(BOOL)animated
NS_DEPRECATED_IOS(2_0, 3_2) __TVOS_PROHIBITED;
 // use -setStatusBarHidden:withAnimation:
- (void)setStatusBarHidden:(BOOL)hidden withAnimation:(UIStatusBarAnimation)animation
NS_DEPRECATED_IOS(3_2, 9_0, "Use -[UIViewController prefersStatusBarHidden]") __TVOS_PROHIBITED;

注意:让我们先来看看// Setting statusBarHidden does nothing if your application is using the default UIViewController-based status bar system.这个注释提示,苹果提示开发者如果使用的是系统基础的状态栏样式你的这些设置是不生效的,在接下来要介绍的通过Info.plist隐藏状态栏同样要注意这件事。

Info.plist中添加一个View controller-based status bar appearance设置选项,设置为NO这样就可以使用上边的方法了

注意:添加的View controller-based status bar appearanceBool类型,默认为Yes,很不幸iOS9之后苹果已经不推荐使用这些方法了,这些方法能用但是会报警告。

那么这些方法被禁用以后,如何操作呢?注释里已经提示Use -[UIViewController prefersStatusBarHidden]这是iOS7之后苹果在UIViewController里添加的新方法,这么做的目的可以让开发者更加灵活的自定义每个ViewController的状态栏。

- (BOOL)prefersStatusBarHidden{
  return YES;
}

iOS7之后UIViewController中不只提供了这个关于状态栏的设置的函数,还有其他的,后面详细说。

方法二:通过Info.plist控制

1,首先我们依然要设置这个(第2步中的两种方式都要设置这个参数)

2,然后设置(两种方式)

或者

两者是等效的!并且两者的状态是同步的。

二、状态栏样式

先看看都有哪些样式(解释看注释)

typedef NS_ENUM(NSInteger, UIStatusBarStyle) {
//默认样式,黑字透明状态栏,适合用于背景色为亮色的页面
  UIStatusBarStyleDefault                   = 0, // Dark content, for use on light backgrounds
//白字透明状态栏,适合用于背景色为暗色的页面
  UIStatusBarStyleLightContent   NS_ENUM_AVAILABLE_IOS(7_0) = 1, // Light content, for use on dark backgrounds

// iOS7.0以前黑底白字,iOS7以后跟UIStatusBarStyleLightContent效果一样
  UIStatusBarStyleBlackTranslucent NS_ENUM_DEPRECATED_IOS(2_0, 7_0, "Use UIStatusBarStyleLightContent") = 1,
// iOS7.0以前启动页为灰底白字,iOS7以后跟UIStatusBarStyleLightContent效果一样
  UIStatusBarStyleBlackOpaque   NS_ENUM_DEPRECATED_IOS(2_0, 7_0, "Use UIStatusBarStyleLightContent") = 2,
} __TVOS_PROHIBITED;

如何设置状态栏样式

// Setting the statusBarStyle does nothing if your application is using the default UIViewController-based status bar system.
@property(readwrite, nonatomic) UIStatusBarStyle statusBarStyle
NS_DEPRECATED_IOS(2_0, 9_0, "Use -[UIViewController preferredStatusBarStyle]") __TVOS_PROHIBITED;
- (void)setStatusBarStyle:(UIStatusBarStyle)statusBarStyle animated:(BOOL)animated
NS_DEPRECATED_IOS(2_0, 9_0, "Use -[UIViewController preferredStatusBarStyle]") __TVOS_PROHIBITED;

同样iOS9以后这些方法被禁用了,苹果推荐在具体的viewControllerUse -[UIViewController preferredStatusBarStyle]

- (UIStatusBarStyle)preferredStatusBarStyle{
  return UIStatusBarStyleLightContent;
}

注意:我们通常使用的viewController都是嵌套在UINavigationController中使用的,此时在viewController中使用- (UIStatusBarStyle)preferredStatusBarStyle;函数会发现设置并没有生效。

系统也给我们提供了一个函数- (UIViewController *)childViewControllerForStatusBarStyle,也可以解决这个问题,后面会讲。

三、背景色

iOS7以后默认情况下状态栏的背景为透明的,一种办法是我们自己写一个UIView作为背景添加到状态栏下面,这样就可以随意设置状态栏的颜色了。

另一种方法就是通过设置navigationBarsetBarTintColor颜色来改变状态栏颜色

UIViewController中其他有关状态栏的函数

preferredStatusBarUpdateAnimation函数

- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation
NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED; // Defaults to UIStatusBarAnimationFade

如果想在当前已经显示的UIViewController中更改状态栏的样式的话,需要调用以上函数。调用该函数后,系统会主动调用preferredStatusBarStyle方法重绘状态栏的样式

childViewControllerForStatusBarStyle函数

// Override to return a child view controller or nil. If non-nil, that view controller's status bar appearance attributes will be used. If nil, self is used. Whenever the return values from these methods change, -setNeedsUpdatedStatusBarAttributes should be called.
- (nullable UIViewController *)childViewControllerForStatusBarStyle
NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED;

这个函数的返回值默认返回nil,此时系统就会调用当前viewControllerApreferredStatusBarStyle函数;如果返回值是另一个viewControllerB那么系统就会调用viewControllerBpreferredStatusBarStyle函数。

运用这个函数就可以解决嵌套UINavigationController设置样式无效的问题。

解释一下为什么嵌套UINavigationControllerviewControllerpreferredStatusBarStyle函数设置无效:

在我们嵌套了UINavigationController的时候,我们的AppDelegate.window.rootViewController通常是我们创建的navigationController,这时首先会调用的是navigationController中的childViewControllerForStatusBarStyle函数,因为默认返回nil,那么接下来就会调用navigationController本身的preferredStatusBarStyle函数,所以我们在viewController中通过preferredStatusBarStyle函数设置的状态栏样式就不会被调用发现,所以也就无效了。

所以我们要自己创建一个继承于UINavigationcontrollerNavigationController,在这个子类中重写childViewControllerForStatusBarStyle函数

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

这样navigationController中的childViewControllerForStatusBarStyle函数会返回navigationController中最上层的viewController,那么viewController中的preferredStatusBarStyle函数的设置就会被系统获知

childViewControllerForStatusBarHidden函数

- (nullable UIViewController *)childViewControllerForStatusBarHidden 

NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED;

childViewControllerForStatusBarHidden函数的使用原理同上,不再赘述。

preferredStatusBarUpdateAnimation函数

// Override to return the type of animation that should be used for status bar changes for this view controller. This currently only affects changes to prefersStatusBarHidden.
- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation
NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED; // Defaults to UIStatusBarAnimationFade

动画形式如下

typedef NS_ENUM(NSInteger, UIStatusBarAnimation) {
  UIStatusBarAnimationNone,
  UIStatusBarAnimationFade NS_ENUM_AVAILABLE_IOS(3_2),
  UIStatusBarAnimationSlide NS_ENUM_AVAILABLE_IOS(3_2),
} __TVOS_PROHIBITED;

这个函数返回了动画效果。动画效果只有在prefersStatusBarHidden函数返回值变化的时候才会展示,同时要通过调用
[self setNeedsStatusBarAppearanceUpdate]函数来重绘状态栏

四、应用

我们可以通过隐藏系统状态栏,然后自定义UIWindow通过设置setWindowLevel:UIWindowLevelStatusBar实现自定义状态栏。

总结

以上就是这篇文章的全部内容了,希望能对各位iOS开发者们有所帮助,如果有疑问大家可以留言交流。

(0)

相关推荐

  • iOS 设置状态栏的背景颜色方法

    设置状态栏的背景颜色 - (void)setStatusBarBackgroundColor:(UIColor *)color { UIView *statusBar = [[[UIApplication sharedApplication] valueForKey:@"statusBarWindow"] valueForKey:@"statusBar"]; if ([statusBar respondsToSelector:@selector(setBackgro

  • IOS 开发状态栏隐藏的实现办法

    IOS 开发状态栏隐藏的实现办法 解决方法:  IOS7以下版本隐藏UIStatusBar的方法: - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [application setStatusBarHidden:YES]; return YES; } 升级到iOS7后的方法: 在基类中重载UIViewController.h

  • 详解在iOS App中自定义和隐藏状态栏的方法

    自定义状态栏 有时候,需要在状态栏上显示一些自定义信息,比如新浪微博的官方iOS客户端:告知用户信息处于发送队列.发送成功或者发送失败. 如上图,通过在状态栏显示自定义信息,可以给用户友好又不影响软件使用的提示. 为此,我们显得定义一个自定义状态栏类,包含一个显示信息的Label: 复制代码 代码如下: @interface CustomStatusBar : UIWindow  {      UILabel *_messageLabel;  }    - (void)showStatusMes

  • 图文讲解如何解决App的iOS 7顶部状态栏适配问题

    首先说明下,ios7中,由于status bar不再占用单独的20px,如果app需要同时支持ios7和ios6.1以下,那就需要适配下了,适配开始: 先看用xcode新建项目后 IOS7和IOS6上的的运行效果: ps:一个empty application 里面+了一个rootcontroller,作为window的根控制器,view里面放了一个tableview; 是不是遇到的IOS7的新问题,状态栏跟tableview重叠了,OK,看见这个不想看到的结果,下面我们就开始正式的解决掉这个招

  • iOS 隐藏导航条和状态栏实现方法

     iOS  隐藏导航条和状态栏实现方法 状态栏的高度是20,导航栏的高度是44,如果同时存在状态栏的导航条,我们通常会设置view上的控件的位置的X 大于等于 64. 一:隐藏导航条:self.navigationController.navigationBarHidden = YES; 二:隐藏状态栏: 第一步:在info.plist 文件里增加两个类型(Type)为bool 选项, Status bar is initially hidden 设为YES:View controller-ba

  • iOS实现点击状态栏自动回到顶部效果详解

    前言 大家都知道实现状态栏(statusBar)点击自动回到顶部效果,旨在为用户在浏览界面时提供便利,点击状态栏能够快速回到界面顶部,所以主要针对可以滚动的UIScrollView和其子类UITableVIew和UICollectionView. 这里将从以下几个方面实现该功能. 1.苹果自带功能 分析: 首先,苹果自己已经提供了该功能,往上滑动tabView,点击statusBar,tableView会自动回到初始位置.如下图所示,此时点击statusBar,屏幕最上方显示的将是第一个cell

  • iOS在状态栏上显示提醒信息的功能定制

    先看效果图 实现这个效果,用到了JDStatusBarNotification,这是一个易于使用和定制的在状态栏上显示提醒信息的控件,可自定义颜色.字体以及动画,支持进度条展示,并可以显示活动指示器. 假设这么一个场景,需要调接口修改个人资料,这时有3个状态,正在修改.修改成功.修改失败.我们可以写一个公共类,方便调用,譬如 NSObject+Common. .h文件写方法 #import <Foundation/Foundation.h> @interface NSObject (Commo

  • IOS点击按钮隐藏状态栏详解及实例代码

    IOS点击按钮隐藏状态栏详解 前言: 最近学习IOS的基础知识,实现隐藏状态栏的功能,这里就记录下来,希望对大家有所帮助 实例代码: @interface SecondViewController () @property (nonatomic, assign,getter=isHideStatus) BOOL hideStatus; @end @implementation SecondViewController - (void)viewDidLoad { [super viewDidLoa

  • iOS 自定义状态栏和导航栏详细介绍

    iOS 自定义状态栏和导航栏 开发IOS APP 经常会根据需求更改状态栏和导航栏,这里整理了几种方法,大家可以看下. 导航栏透明 -(void)viewWillAppear:(BOOL)animated { //viewWillAppear中设置透明 [super viewWillAppear:animated]; [self.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault]; /

  • 深入理解iOS的状态栏

    一.状态栏的隐藏 状态栏的隐藏主要有两种方法,下面来一起看看吧. 方法一:通过代码控制 @interface UIApplication(UIApplicationDeprecated) // Setting statusBarHidden does nothing if your application is using the default UIViewController-based status bar system. @property(readwrite, nonatomic,ge

  • 轻松理解iOS 11中webview的视口

    iOS 11在状态栏区域带来了一些新的,也许是不直观的行为,这对使用Apache Cordova或Ionic等工具的开发人员尤为重要.尤其是这种行为变化会影响到任何基于Web的应用程序,这些应用程序在进行iOS 11构建时使用fixed定位标题栏.此文章可帮助您了解iOS 11中的Webview视口. 注意:现有应用程序将继续工作,因为它们始终可以对其视口行为进行更改.这只会影响使用Xcode 9和iOS 11的目标编译的应用程序. 要了解这些变化,我们需要看看它的历史. 状态栏与安全区 在早起

  • 30分钟快速带你理解iOS中的谓词NSPredicate

    一.引言 在现代汉语的解释中,谓词是用来描述或判断客体性质.特征或者客体之间关系的词项.通俗的说,它是描述事物属性的.在iOS开发Cocoa框架中,有提供NSPredicate类,这个类通常也被成为谓词类,其主要的作用是在Cocoa中帮助查询和检索,但是需要注意,实质上谓词并不是提供查询和检索的支持,它是一种描述查询检索条件的方式,就像更加标准通用的正则表达式一样. NSPredicate提供的谓词可以分为两类:比较谓词和复合谓词. 比较谓词:比较谓词通过使用比较运算符来描述所符合条件的属性状态

  • iOS中状态栏的基本使用方法汇总

    一.状态栏与导航栏 状态栏:显示时间.电池等信息 导航栏:显示app页面标题,返回按钮等 iOS7之前:状态栏与导航栏是分开的: iOS7之后:状态栏与导航栏合在一起:导航部分总高度(64)= 状态栏高度(20) +导航栏内容高度((44) iPhoneX设备出现以后,状态栏的高度变为44,导航栏部分总高度(88) = 状态栏(44) + 导航栏内容高度(44) 二.设置状态栏显隐与字体样式 iOS状态栏可以设置显示和隐藏,也可以设置文字的颜色.通过修改info.plist中的View cont

  • 深入理解IOS控件布局之Masonry布局框架

    前言: 回想起2013年做iOS开发的时候,那时候并没有采用手写布局代码的方式,而是采用xib文件来编写,如果使用纯代码方式是基于window的size(320,480)计算出一个相对位置进行布局,那个时候windows的size是固定不变的,随着iphone5的发布,windows的size(320,568)也发生了变化,而采用autoresizingMask的方式进行适配,到后来iphone 6之后windows size的宽度也随之变化,开始抛弃autoresizingMask改用auto

  • 理解iOS多线程应用的开发以及线程的创建方法

    一.进程和线程 1.什么是进程   进程是指在系统中正在运行的一个应用程序 每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内 比如同时打开QQ.Xcode,系统就会分别启动2个进程 通过"活动监视器"可以查看Mac系统中所开启的进程   2.什么是线程 1个进程要想执行任务,必须得有线程(每1个进程至少要有1条线程) 线程是进程的基本执行单元,一个进程(程序)的所有任务都在线程中执行 比如使用酷狗播放音乐.使用迅雷下载电影,都需要在线程中执行 3.线程的串行   1个线

随机推荐