在iOS 6中,隐藏Status Bar很的简单。

// iOS 6及曾经,隐藏状态栏
[[UIApplication sharedApplication] setStatusBarHidden:YES];

来到了iOS 7的年代以后,须要在UIViewController中指定:

#ifdef __IPHONE_7_0
- (BOOL)prefersStatusBarHidden {
return YES;
}
#endif

并通过下列代码刷新状态栏:

if ([viewController respondsToSelector:@selector(setNeedsStatusBarAppearanceUpdate)]) {
[viewController prefersStatusBarHidden];
[viewController performSelector:@selector(setNeedsStatusBarAppearanceUpdate)];
}

可是上述代码并非万能的,iOS 7的某些场合还是会造成无法隐藏Status Bar的问题。

在ParentViewController中Add一个ChildViewController,假设ParentViewController的

prefersStatusBarHidden方法返回的是NO,那么即使ChildViewController中的prefersStatusBarHidden方法返回的是YES并调用以上代码。也无法隐藏Status Bar。

解决方式:Method Swizzling

在ChildViewController中Hook ParentViewController的prefersStatusBarHidden方法,使其返回YES,然后调用更新状态栏的代码,实现隐藏状态栏。须要注意的是。在适当场合,比如ChildViewController的viewWillDisappear方法中。须要将Hook的方法还原。否则可能造成奇怪的情况出现。

代码例如以下:

1.在ChildViewController的viewDidLoad方法中替换ParentViewController的prefersStatusBarHidden方法的实现

- (void)viewDidLoad {
[super viewDidLoad]; _statusBarHidden = [UIApplication sharedApplication].statusBarHidden;
// 进入界面时隐藏状态栏
UIViewController *parentViewController = self.parentViewController;
if ([parentViewController respondsToSelector:@selector(setNeedsStatusBarAppearanceUpdate)]) {
[self hookPrefersStatusBarHidden:parentViewController];
}
else {
// iOS 6及曾经,隐藏状态栏
[[UIApplication sharedApplication] setStatusBarHidden:YES];
}
}

2.使用Runtime的Method Swizzling大法替换ChildViewController和ParentViewController两者的prefersStatusBarHidden方法的实现

- (void)hookPrefersStatusBarHidden:(UIViewController *)parentViewController {
/**
Method Swizzling 1.假设ParentViewController的prefersStatusBarHidden返回NO。那么Add在其上的ChildViewController的prefersStatusBarHidden即使返回YES,也无法隐藏状态栏。因此在viewDidLoad时。须要将ParentViewController中prefersStatusBarHidden方法的实现替换掉
2.在viewWillDisappear时。须要将交换的方法实现还原回来
*/
Method src_method = class_getInstanceMethod([UIViewController class], @selector(prefersStatusBarHidden));
Method des_method = class_getInstanceMethod([self class], @selector(hook_prefersStatusBarHidden));
method_exchangeImplementations(src_method, des_method); // 刷新状态栏
dispatch_async(dispatch_get_main_queue(), ^{
[parentViewController prefersStatusBarHidden];
[parentViewController performSelector:@selector(setNeedsStatusBarAppearanceUpdate)];
});
} - (BOOL)hook_prefersStatusBarHidden {
// 隐藏状态栏
return YES;
}

3.在ChildViewController从ParentViewController中移除时。viewWillDisappear方法必然会被调用(注意不要在viewDidDisappear方法中调用,此时ChildViewController可能已经被释放掉),因此能够在该方法中还原两者的prefersStatusBarHidden的实现

- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated]; // 退出界面时。还原状态栏的初始状态
UIViewController *parentViewController = self.parentViewController;
if ([parentViewController respondsToSelector:@selector(setNeedsStatusBarAppearanceUpdate)]) {
[self hookPrefersStatusBarHidden:parentViewController];
}
else {
// iOS 6及曾经,恢复状态栏的初始状态
[[UIApplication sharedApplication] setStatusBarHidden:_statusBarHidden];
}
}

有时候为了确保状态栏隐藏。能够强制运行以上代码。

在实际project中第二次用上Runtime的特性。实在开心,哈哈。

參考资料:

iOS7 隐藏状态栏 (电池栏)

Objective-C的hook方案(一): Method Swizzling

iOS 使用Method Swizzling隐藏Status Bar的更多相关文章

  1. 隐藏 Status Bar

    iOS6和iOS7在隐藏 Status Bar 三种方式比较: Storyboard 界面上选中UIViewController,最右边Simulated Metrics找到 Status Bar 设 ...

  2. iOS7下隐藏status bar的详细研究

    info.plist文件中,View controller-based status bar appearance项设为YES,则View controller对status bar的设置优先级高于a ...

  3. ios7上隐藏status bar

    在iOS7上 对于设置status bar 又有了点点的改变 1.对于 UIViewController 加入了动态改变 status bar style的方法 - (UIStatusBarStyle ...

  4. iOS7中彻底隐藏status bar

    用Xcode5开发新游戏,发现在iOS7中按照以前的方法隐藏status bar失效了. 想要彻底隐藏status bar,需要在info.plist中添加新行“View controller-bas ...

  5. ios开发中如何隐藏各种bar

    转载自http://www.cnblogs.com/lovecode/articles/2234557.html 状态条Status Bar [UIApplication sharedApplicat ...

  6. iOS 隐藏Status Bar

    要隐藏,有3个地方要做: 1.在info.Plist里,将该属性的hidden,设置为YES,这样,在启动时,就不会显示了: 2.在application-didFinish里面写,这样,可以隐藏io ...

  7. ios7适配--隐藏status bar

    //viewDidload if ([self respondsToSelector:@selector(setNeedsStatusBarAppearanceUpdate)]) { // iOS 7 ...

  8. iOS开发-UINavigationBar和Status Bar实用技巧

    iOS7之后关于UINavigationBar和Status  Bar都发生了一系列的改变,如果不需要兼容iOS7之后的设备,按照网上有些资料去解决问题会踩到一些坑.在iOS 7中,我们可以修改每个V ...

  9. Status bar and navigation bar appear over my view's bounds in iOS 7

    转自:http://stackoverflow.com/questions/17074365/status-bar-and-navigation-bar-appear-over-my-views-bo ...

随机推荐

  1. 用ATL和MFC来创建ActiveX控件

    摘要:目前MFC和ATL代表了两种框架,分别面向不同类型的基于Windows的开发.MFC代表了创建独立的Windows应用的一种简单.一致的方法:ATL提供了一种框架来实现创建COM客户机和服务器所 ...

  2. java常量池理解

    String类两种不同的创建方式 String s1 = "zheng"; //第一种创建方式 String s2 = new String("junxiang" ...

  3. sparse autoencoder

    1.autoencoder autoencoder的目标是通过学习函数,获得其隐藏层作为学习到的新特征. 从L1到L2的过程成为解构,从L2到L3的过程称为重构. 每一层的输出使用sigmoid方法, ...

  4. VS2015 开发人员命令提示,如何实现记事本编程

    开始,选择VS2015 开发人员命令提示,打开 找到.c文件的位置,复制位置 在VS2015 开发人员命令提示, 输入cd 位置 回车 然后输入cl 文件名 回车 这样进行编译

  5. Swift 设置navigation左右两侧按钮

    我们以设置右侧按钮为例,左侧方法类似 方法一,直接自定义文字 let item=UIBarButtonItem(title: "分享", style: UIBarButtonIte ...

  6. BZOJ 2186 SDOI2008 沙拉公主的困惑 数论

    题目大意:给定询问组数T和取模数P,每次询问给定两个整数n和m,求1~(n!)的数中与m!互质的数个个数模P (m<=n) 首先T<=1W,暴力肯定过不去,我们须要预处理一些东西 首先我们 ...

  7. 自学SQL语言的例子(使用MySQL实现)

    SQL语言作为一种数据库管理的标准语言有着极为广泛的应用场景,菜鸟入门选用的数据库软件是轻量级的免费(这个极为重要)的MySQL,下载链接如下:http://www.mysql.com/downloa ...

  8. 我的小前端 (1)—— 安卓机和ios机的区别

    没有什么特别新技术,就是记录我做移动端遇到的问题 2016-02-16 微信,支付宝和APP都会遇到这些问题 一.安卓机和ios机的区别 1.常用 <head>        <me ...

  9. javascript中对象的不同创建方法

    javascript中的对象与一般的面向对象的程序设计语言(c++,Java等)不同,甚至很少有人说它是面向对象的程序设计语言,因为它没有类.javaScript只有对象,不是类的实例.javascr ...

  10. JavaScript的一点简介(注:本文诸多观点源于JavaScript高级程序设计,如有侵权,立即删除)

    JavaScript是一门最易让人误解的语言,该语言中精华与糟粕并存(可能比一般语言的这个比例要大一些):但“千淘万漉虽辛苦,吹尽黄沙始到金”,层层面纱下是易用灵活.优雅轻灵的内在.很久以前,Java ...