iOS 7:用代码解决视图控制器的View整体上移问题
2014-04-14 10:46
369 查看
如果你准备将你的老的 iOS 6 app 迁移到 iOS 7 上,那么你必须注意了。当你的老的 app 在 iOS 7 设备上运行时,所有ViewController 的视图都整体上移了,因为 iOS 7 把整个屏幕高度(包括状态栏和导航栏)都作为了视图控制器的有效高度。于是你的视图上移了,并和上层的状态栏交叠在一起。
你当然可以在 Xcode 中修改每个 View,将他们下移20个像素(状态栏高度)或者64个像素(状态栏+导航栏高度)。
但是苹果显然已经考虑到这个问题,他们在 iOS 7 SDK 中为 ViewController 提供了一个 edgesForExtendedLayout 新属性。如果你将这个属性设置为UIRectEdgeNone,则 viewController 的所有子视图都会自动调整,这样在 iOS 7 下看到的效果和 iOS 6 完全一样。
为了方便,你可以为 UIViewController 扩展一个子类,并覆盖它的 viewDidLoad 方法:
@implementation DerivedViewController
- (void)viewDidLoad
{
[superviewDidLoad];
if ([selfrespondsToSelector:@selector(edgesForExtendedLayout)])
self.edgesForExtendedLayout = UIRectEdgeNone;
}
@end
然后你以后所有的 ViewController 都从这个 DerivedViewController 类继承。
但不幸的是,我们的程序仍然有大量 iOS<7 的用户 ,我们无法立即抛弃对 iOS 6 的支持。无论 edgesForExtendedLayout 还是UIRectEdgeNone,都只能在 iOS7 下有效。对于 iOS 6,我将以上代码修改为:
- (void)viewDidLoad
{
[superviewDidLoad];
#if__IPHONE_OS_VERSION_MAX_ALLOWED >= 70000
if ([selfrespondsToSelector:@selector(edgesForExtendedLayout)])
self.edgesForExtendedLayout = UIRectEdgeNone;
#else
float barHeight =0;
if (!isIPad()&& ![[UIApplication sharedApplication] isStatusBarHidden]) {
barHeight+=([[UIApplication sharedApplication]statusBarFrame]).size.height;
}
if(self.navigationController &&!self.navigationController.navigationBarHidden) {
barHeight+=self.navigationController.navigationBar.frame.size.height;
}
for (UIView *viewin self.view.subviews) {
if ([view isKindOfClass:[UIScrollView class]]) {
view.frame = CGRectMake(view.frame.origin.x, view.frame.origin.y +barHeight, view.frame.size.width, view.frame.size.height - barHeight);
} else {
view.frame = CGRectMake(view.frame.origin.x, view.frame.origin.y +barHeight, view.frame.size.width, view.frame.size.height);
}
}
#endif
}
通过宏 __IPHONE_OS_VERSION_MAX_ALLOWED 判断 deployment target 是否 >7.0。>7.0则使用新的 edgesForExtendedLayout API,负责使用比较笨的方法逐个下移 subviews,并自动根据状态栏/导航栏的可视状态计算要移动的偏移量。
注:如果已升级至Xcode5,将导航控制器的 Top Bar 设置为一种“Opacque ...”(不透明)类型可解决此问题。
转自 http://blog.csdn.net/kmyhy/article/details/20444611
你当然可以在 Xcode 中修改每个 View,将他们下移20个像素(状态栏高度)或者64个像素(状态栏+导航栏高度)。
但是苹果显然已经考虑到这个问题,他们在 iOS 7 SDK 中为 ViewController 提供了一个 edgesForExtendedLayout 新属性。如果你将这个属性设置为UIRectEdgeNone,则 viewController 的所有子视图都会自动调整,这样在 iOS 7 下看到的效果和 iOS 6 完全一样。
为了方便,你可以为 UIViewController 扩展一个子类,并覆盖它的 viewDidLoad 方法:
@implementation DerivedViewController
- (void)viewDidLoad
{
[superviewDidLoad];
if ([selfrespondsToSelector:@selector(edgesForExtendedLayout)])
self.edgesForExtendedLayout = UIRectEdgeNone;
}
@end
然后你以后所有的 ViewController 都从这个 DerivedViewController 类继承。
但不幸的是,我们的程序仍然有大量 iOS<7 的用户 ,我们无法立即抛弃对 iOS 6 的支持。无论 edgesForExtendedLayout 还是UIRectEdgeNone,都只能在 iOS7 下有效。对于 iOS 6,我将以上代码修改为:
- (void)viewDidLoad
{
[superviewDidLoad];
#if__IPHONE_OS_VERSION_MAX_ALLOWED >= 70000
if ([selfrespondsToSelector:@selector(edgesForExtendedLayout)])
self.edgesForExtendedLayout = UIRectEdgeNone;
#else
float barHeight =0;
if (!isIPad()&& ![[UIApplication sharedApplication] isStatusBarHidden]) {
barHeight+=([[UIApplication sharedApplication]statusBarFrame]).size.height;
}
if(self.navigationController &&!self.navigationController.navigationBarHidden) {
barHeight+=self.navigationController.navigationBar.frame.size.height;
}
for (UIView *viewin self.view.subviews) {
if ([view isKindOfClass:[UIScrollView class]]) {
view.frame = CGRectMake(view.frame.origin.x, view.frame.origin.y +barHeight, view.frame.size.width, view.frame.size.height - barHeight);
} else {
view.frame = CGRectMake(view.frame.origin.x, view.frame.origin.y +barHeight, view.frame.size.width, view.frame.size.height);
}
}
#endif
}
通过宏 __IPHONE_OS_VERSION_MAX_ALLOWED 判断 deployment target 是否 >7.0。>7.0则使用新的 edgesForExtendedLayout API,负责使用比较笨的方法逐个下移 subviews,并自动根据状态栏/导航栏的可视状态计算要移动的偏移量。
注:如果已升级至Xcode5,将导航控制器的 Top Bar 设置为一种“Opacque ...”(不透明)类型可解决此问题。
转自 http://blog.csdn.net/kmyhy/article/details/20444611
相关文章推荐
- iOS 7:用代码解决视图控制器的View整体上移问题
- iOS 7:用代码解决视图控制器的View整体上移问题
- iOS 7:用代码解决视图控制器的View整体上移问题[转载]
- iOS 7:用代码解决视图控制器的View整体上移问题
- iOS 7:用代码解决视图控制器的View整体上移问题
- iOS 7:用代码解决视图控制器的View整体上移问题
- iOS 7 :解决ViewController的View整体上移的问题
- 关于JKAlertDialog在多个视图控制器跳转后不能正常显示的问题的解决--IOS
- 因IOS版本导致的模态视图控制器dismissModalViewControllerAnimated调用问题
- iOS 之控制器view显示中view的父子关系及controller的父子关系_解决屏幕旋转不能传递事件问题
- iOS 当前视图控制器view.frame 在viewDidLoad 和 viewWillAppear 中值不一样问题
- 猫猫学iOS 之控制器view显示中view的父子关系及controller的父子关系_解决屏幕旋转不能传递事件问题
- AJ学IOS 之控制器view显示中view的父子关系及controller的父子关系_解决屏幕旋转不能传递事件问题
- iOS 视图控制器(ViewController)中的代码规范
- IOS开发---菜鸟学习之路--(二十四)-iOS7View被导航栏遮挡问题的解决
- iOS 视图切换问题 popViewControllerAnimated 视图刷新问题
- iOS开发中解决UIScrollView滚动时NSTimer失效的问题
- iOS tableView分割线问题解决方法
- 实例讲解iOS中的UIPageViewController翻页视图控制器
- android RecycleView解决多线程情况下图片错乱问题与OOM问题(原生代码,无插件)