近日,我对项目进行了iOS7适配,迟迟没有使用7.0SDK是因为旧工程使用iOS7.0有一些问题,趁着这次机会,我详细整理了适配iOS7需要注意的几个地方。记录如下:
一,iOS7 UITableViewCell适配
(1)iOS7 UITableViewCell背景色
在iOS7之前UITableViewCell的backgroundColor是透明的,但在iOS7中默认白色背景,如果使用iOS7 SDK的UITableViewCell显示不正常,只需要需修改:
[cell setBackgroundColor:[UIColor clearColor]];
(2)iOS7 UITableViewCell层次关系
iOS7之前,遇到UITableViewCell上的UIButton子视图找到该UITableViewCell时,也许会有这样的代码: [[sender superview] superview]
这段代码在iOS7上肯定会崩溃。
iOS7以前,我们一般是把视图添加到UITableViewCell的contentView上,contentView的父视图是
UITableViewCell,上面的代码是没有问题的。但在iOS7上,UITableViewCell的contentView的父视图是
UITableViewCellContentView[SDK中好像没有这个类的详细介绍],所以 [[sender superview]
superview]就找不到UITableViewCell。对UiscrollView不明确的看IOS研究之滚动视图UIScrollView的简单应用
实际上这里的正确做法应该是:
在继承UITableView的类中实现UIButton的触发方法:
1 2 3 4 5 6 |
-(void)buttonClick:(UIButton CGPoint buttonPosition NSIndexPath *indexPath UITableViewCell *cell //do something } |
二,iOS7 UIViewController适配
最大的变化是UIViewController默认都是全屏显示的。
(1)导航栏高度
iOS7之前导航栏高度为44,iOS7是全屏布局,导航栏高度包括了状态栏高度20变成了64。如果不适配状态栏就会把导航栏遮住。
(2)edgesForExtendedLayout
有如下取值
UIRectEdgeNone = 0,
UIRectEdgeTop = 1 << 0,
UIRectEdgeLeft = 1 << 1,
UIRectEdgeBottom = 1 << 2,
UIRectEdgeRight = 1 << 3,
UIRectEdgeAll
这个值只在当前视图有navigationBar或者tabBar时有效,如果是自定义的navigationBar/tabBar,这个值是不起作用
的。它标示从上下左右方向页面延伸,也就是导航栏页面也算在视图显示的部分。iOS7默认是全屏布局,取值就是UIRectEdgeAll。如果之前是通
过iOS 6.0SDK编译的,估计就要改成
self.edgesForExtendedLayout = UIRectEdgeNone才能在iOS 7上显示没有问题。
同理的还有[都是在有navigationBar/tabBar时有效];
self.extendedLayoutIncludesOpaqueBars = NO;
指定了当Bar使用了不透明图片时,视图是否延伸至Bar所在区域,默认值时NO。所以我们如果自定义了导航栏的背景图片,那么视图会从导航栏以下开始,不会延伸到导航栏区域。
self.modalPresentationCapturesStatusBarAppearance = NO;
self.tabBarController.tabBar.translucent = NO;
self.navigationController.navigationBar.translucent = NO;//设置导航栏半透明效果
(3)automaticallyAdjustsScrollViewInsets
第一个添加到UIViewController上的UIView,如UIScrollView(包括其子类,比如UITableVie)等会自动在顶部和
底部预留一些空白,主要是为了滚动经过半透明导航条或者tabbar下是能看到的半透明的效果,是否预留空白可以由UIViewController的
automaticallyAdjustsScrollViewInsets的这个属性控制。
三,iOS7 状态栏
涉及状态栏操作的XXX-info.plist属性有如下几个:
Status bar style
Status bar is initially hidden
Status bar tinting parameters
View controller-based status bar appearance
其中Status bar is initially hidden,Status bar style(tekuba.net测试好像在iOS6上不起作用)分别标示全局的设置:状态栏是否隐藏,以及状态栏的风格。
对应着的代码分别是:
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:NO];
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
一般情况下,我们希望程序启动时隐藏状态栏而程序启动完成进入前台后显示状态栏,这个时候就可以设置plist文件的Status bar is
initially hidden为YES,先隐藏状态栏,然后在didFinishLaunchingWithOptions方法中设置:
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:NO]显示状态栏。
1,iOS7以前不能针对每一个UIViewController单独控制状态栏的显示隐藏,只能在需要的时候调用setStatusBarHidden/setStatusBarStyle修改状态栏显示或者样式
2,iOS7以后,状态栏是透明的。
plist参数多了一个View controller-based status bar appearance。
如果View controller-based status bar appearance为NO,则标示状态栏不受UIViewController的单独控制,那么这个时候状态栏的控制还和iOS7以前的方式一样,在需要修改的地方执行setStatusBarHidden。
而如果设置为YES,则状态栏会根据各个UIViewController的配置改变,UIViewController中如果需要改变状态栏则需要重载以下两个方法:
- (UIStatusBarStyle)preferredStatusBarStyle
{
return UIStatusBarStyleLightContent;//状态栏样式
}
- (BOOL)prefersStatusBarHidden
{
return NO;//状态栏是否隐藏
}
1 2 3 4 5 6 7 8 9 |
- (UIStatusBarStyle)preferredStatusBarStyle { return UIStatusBarStyleLightContent;//状态栏样式 } - (BOOL)prefersStatusBarHidden { return NO;//状态栏是否隐藏 } |
UIViewController初始化的时候会自动执行这个两个方法,之后如果需要刷新状态栏样式的时候,调用[self setNeedsStatusBarAppearanceUpdate]即可,系统会自动调用这两个方法。
四,具体实施
如果是使用了系统自带的导航栏和标签栏,则按照以上设置基本上就会没有问题。如果是自定义的导航栏和标签栏,需要做些小改动:
//判断是否ios7
#define isIOS7 ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7)
#define NAV_HEIGHT ( isIOS7 ? 64 : 44) //导航栏高度
#define NAV_HEIGHT_NO_STATUSVIEW 44 //导航栏高度-不包含状态栏
#define NAV_START_Y (NAV_HEIGHT – NAV_HEIGHT_NO_STATUSVIEW)//导航栏绘制时的起始Y值
创建windows时
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
在使用时创建自定义的导航栏高度为NAV_HEIGHT,绘制自定义视图的开始Y坐标为NAV_START_Y。
另外在一些地方也许还需要加上:
if (isIOS7) {
self.automaticallyAdjustsScrollViewInsets = NO;
}
1 2 3 |
if (isIOS7) { self.automaticallyAdjustsScrollViewInsets = NO; } |