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 ...
随机推荐
- Android开发:自定义GridView/ListView数据源
http://mobile.51cto.com/android-259861.htm 在开发中,我们常常会遇到比较复杂的GridView/ListView的布局,重新实现BaseAdapter不但能帮 ...
- overload的一点思考
仅参数类型不同的重载方法,使用过程的一个困惑: 有没有必要使用instanceof方法? package overload.special; public class OverLoadTest { p ...
- pagespeed 安装(chrome版和firefox版)
原文地址:http://blog.sina.com.cn/s/blog_6c9da636010103va.html pagespeed 让你的网站页面打开速度飞起来! 1.firefox版本下的安装 ...
- SVN 权限配置具体说明
svnserve权限配置 分配权限时.文件夹应该应该遵从从大到小,权限应该从小到大的规则 即:文件夹从根文件夹開始,权限从没有权限(为空就可以)到可写再到可读写. 提示:文件夹的訪问权限既能够分配给组 ...
- 利用分布类防止EF更新模型丢失验证信息
数据库表TT,EF生成的model是这样的.在这里添加代码,从数据库更新模型是会冲掉. //------------------------------------------------------ ...
- 使用win8时删除自带的输入法的好方法
无直接把那个语言都删了,再直接装输入法就行了.
- 自动备份多个MOSS站点集的脚本
自动备份多个站点集的脚本(backupscript.bat)可以生成文件名如"Site80_20140327.bak"的备份文件. @echo offecho ++++++++++ ...
- .net通用权限框架B/S (四)--DAL数据层以及数据接口
数据层以及数据接口设计如下图(以g_orga组织机构和g_role角色)为例,这几个类可以通过.tt模版生成 设计参考学习http://www.cnblogs.com/hanyinglong/arch ...
- MySQL-python 1.2.3 for Windows and Python 2.7, 32bit and 64bit versions -(亲测可用)
MySQL-python 1.2.3 for Windows and Python 2.7, 32bit and 64bit versions - See more at: http://www.co ...
- CentOS添加中科大、163 yum源
首先备份CentOS-Base.repo [root@richard yum.repos.d]# mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos ...