iOS 使用Method Swizzling隐藏Status Bar
在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的特性。实在开心,哈哈。
參考资料:
iOS 使用Method Swizzling隐藏Status Bar的更多相关文章
- 隐藏 Status Bar
iOS6和iOS7在隐藏 Status Bar 三种方式比较: Storyboard 界面上选中UIViewController,最右边Simulated Metrics找到 Status Bar 设 ...
- iOS7下隐藏status bar的详细研究
info.plist文件中,View controller-based status bar appearance项设为YES,则View controller对status bar的设置优先级高于a ...
- ios7上隐藏status bar
在iOS7上 对于设置status bar 又有了点点的改变 1.对于 UIViewController 加入了动态改变 status bar style的方法 - (UIStatusBarStyle ...
- iOS7中彻底隐藏status bar
用Xcode5开发新游戏,发现在iOS7中按照以前的方法隐藏status bar失效了. 想要彻底隐藏status bar,需要在info.plist中添加新行“View controller-bas ...
- ios开发中如何隐藏各种bar
转载自http://www.cnblogs.com/lovecode/articles/2234557.html 状态条Status Bar [UIApplication sharedApplicat ...
- iOS 隐藏Status Bar
要隐藏,有3个地方要做: 1.在info.Plist里,将该属性的hidden,设置为YES,这样,在启动时,就不会显示了: 2.在application-didFinish里面写,这样,可以隐藏io ...
- ios7适配--隐藏status bar
//viewDidload if ([self respondsToSelector:@selector(setNeedsStatusBarAppearanceUpdate)]) { // iOS 7 ...
- iOS开发-UINavigationBar和Status Bar实用技巧
iOS7之后关于UINavigationBar和Status Bar都发生了一系列的改变,如果不需要兼容iOS7之后的设备,按照网上有些资料去解决问题会踩到一些坑.在iOS 7中,我们可以修改每个V ...
- 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 ...
随机推荐
- jQuery validate (转载)
转自:http://blog.sina.com.cn/s/blog_608475eb0100h3h1.html jQuery校验 官网地址:http://bassistance.de/jquery-p ...
- jsp九九乘法表
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding= ...
- StarTeam SDK 13 下载安装
SDK 13据称兼容 StarTeam 11. 下载地址是:ftp://us.ftp.microfocus.com/Starteam/st-sdk-13.0-readme.htm Java用户可以选在 ...
- php的stdClass类
在PHP内核进行模块初始化操作时会自动加载这个函数, 这样,stdClass类的注册操作也就会被执行了.stdClass类是一个没有成员变量也没有成员方法的类. 它的所有的魔术方法,父类.接口等在初始 ...
- hdu4740【杭州网赛、模拟、有点搜索?】
当时看了这题就感觉so easy... 本来不想写的,后来感觉是不是可以练一下搜索水平.. 比赛时有人过了就没写. 比赛完了写一下. 实现还不是那么顺利, 囧 本来自己以为这题能练下搜 ...
- JavaScript、JSP、Java及javaEE
对JavaScript.JSP.Java及javaEE之间区别的理解 JavaScript和Java名字极为类似,相信不少的初学者或者准备学这些知识的人对于JavaScript.JSP.Java及Ja ...
- JavaSE复习日记 : 循环终止语句(break/break outerFor/continue)
最近没网,但攒了几天的博客,这次逮到机会发博客,直接三篇走起; /* * 循环终止语句: break/ break outerFor/ continue */ /* * break语句 * 1. 用于 ...
- Maximum & Minimum Depth of Binary Tree
Given a binary tree, find its maximum depth. The maximum depth is the number of nodes along the long ...
- BZOJ 2878: [Noi2012]迷失游乐园( 树形dp )
一棵树的话直接树形dp(求出往下走和往上走的期望长度). 假如是环套树, 环上的每棵树自己做一遍树形dp, 然后暴力枚举(环上的点<=20)环上每个点跑经过环上的路径就OK了. -------- ...
- 如何实现select组件的选择输入过滤作用
实现select组件的选择输入过滤作用的js代码如下: /** *其中//******之间的部分显示的是在没有选择输入过滤功能的代码上加入的功能代码 ** / (function ( $ ) { $. ...