2014-01-23

iOS适配分为2大块:屏幕分辨率适配iOS7的适配

屏幕分辨率适配

屏幕分辨率适配也就是3.5寸屏幕(640x960) 和 4寸屏幕(640x1136)分辨率不同的适配

  1. autoresingmask
  2. autolayout (支持iOS6以上的系统)

下面主要介绍iOS7的适配。

iOS7适配

先看下iOS7中的一些变化:

  • iOS7中字体格式更加细
  • 为iOS7 准备一个120x120像素的icon ,命名为 icon7.png
  • 所有可以运行iOS 7系统的iPhone都需要Retina显示屏
  • prevMainStoryboard.storyboard 在file inspector 中设置全局的tint color

  • UITableViewCell 选中颜色有原来的蓝色变为了灰色,cell之间的separator不通屏
  • UIAlertView 添加了一个contentView的属性,可以添加自己custom的内容(如图片)
  • UIButton 采用无边框设计,默认type UIButtonTypeRoundedRect遗弃,ios7默认透明效果,新填UIButtonTypeSystem type。
  • UIPikerView iOS7之前都在底部出现,7中的风格适合在view内使用。
  • UISegmentControl 分段控件iOS6种固定44px,可以在代码中修改高度;iOS7中高度固定是29px;
  • UIScrollView

SpriteKit 原生的游戏引擎: SpriteKit + UI Dynamics

**TextKit文本处理框架 ** 基于coretext,简单的方式就可以处理复杂的编排

multitasking 智能化多任务

通过统计用户使用频率和时段来帮助软件在用户刷新之前提前更新数据 。 微博,天气,新闻应用

支持动态字体

iOS7中,用户可以在setting中改变应用字体的大小 (setting-》通用)。 用UIFont类下的preferredFontForTextStyle方法来生成文字,而不是直接指定字体的名称和大小。

着色tintcolor

在iOS 6中,tintColor可以用来给导航栏的背景着色、tab栏、工具栏、搜索栏、搜索栏的范围选择栏着色。而在iOS 7中,给背景着色只需要使用barTintColor属性就可以了。注意导航栏背景色着色使用barTitleColor,而不是ios6中得tintcolor了;栏上按钮的着色还是tintcolor。

各种栏

在iOS7中,状态栏是完全透明的,而其他bar,即navigation bars, tab bars, toolbars, search bars和scope bars都是半透明的。开发者需要保证页面内容能覆盖到这些bar的后面。

UIStatusBar

提供两种状态栏样式: sh UIStatusBarStyleDefault = 0 默认方式,黑色文字,浅色背景时使用 UIStatusBarStyleLightContent = 1 白色文字,深色背景时使用,导航栏背景会作为statusbar的背景

而以下两个旧状态栏样式将被废弃: sh UIStatusBarStyleBlackTranslucent = 1 UIStatusBarStyleLightContent = 2

```sh typedef enum : NSInteger { UIStatusBarStyleDefault, UIStatusBarStyleLightContent,

UIStatusBarStyleBlackTranslucent, UIStatusBarStyleBlackOpaque } UIStatusBarStyle; ```

如何修改statusbar样式?

1) 使用UIApplication的statusBarStyle方法来设置状态栏,但是要停止使用View controller-based status bar appearance,在info.plist 里面把它设置为NO

2) 修改单个view controller中得statusbar。重写viewcontroller 的方法: sh - (UIStatusBarStyle)preferredStatusBarStyle { return UIStatusBarStyleLightContent; }

隐藏statusbar sh - (BOOL)prefersStatusBarHidden { return NO; }

UINavigationBar

继承自UIView。比较大的一个变化是iOS7 navbar要作为status bar的背景,这是因为UINavigationBar里面的_UINavigationBarBackground定位在y方向-20px的位置,然后高度增加到64px,这样就可以同时充当了两者的背景。

iOS7增加一些属性,来改变navigationbar外观:

backIndicatorImage 用来设置返回按钮图片

改变navigationbar样式——barStyle属性 oc typedef enum { UIBarStyleDefault = 0, UIBarStyleBlack = 1, UIBarStyleBlackOpaque = 1, // Deprecated UIBarStyleBlackTranslucent = 2, // Deprecated } UIBarStyle;

改变nav bar的文章或图片颜色—— tintColor oc [[UINavigationBar appearance] setBarTintColor:[UIColor yellowColor]];

translucent 设置半透明效果,bool值。默认值是YES,iOS7中设置成NO: sh self.navigationController.navigationBar.translucent = NO;

修改nav bar 中间的titleView sh self.navigationItem.titleView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"appcoda-logo.png"]]; 将titleView大小设置为bav bar一样,可以用来自定义整个nav bar

设置nav bar 背景为一张图片(自定义一张图片背景) ```sh setBackgroundImage:forBarMetrics:

typedef enum : NSInteger { UIBarMetricsDefault, UIBarMetricsLandscapePhone, UIBarMetricsDefaultPrompt = 101, // Applicable only in bars with the prompt // property,such as UINavigationBar and UISearchBar UIBarMetricsLandscapePhonePrompt, } UIBarMetrics; ```

设置nav bar背景颜色

注意不是tintColor,而是使用barTintColor属性来修改背景色: sh [[UINavigationBar appearance] setBarTintColor:[UIColor yellowColor]]; 也可以找美工弄一张纯色的图,用上面自定义图片背景的方式来设置nav bar 背景颜色。

UIAppearance 协议

调用UINavigationBar的属性和方法来修改navbar。如修改titleText属性:

```sh [[UINavigationBar appearance] setTitleTextAttributes:

    [NSDictionary dictionaryWithObjectsAndKeys:

        [UIColor colorWithRed:255.0/255.0 green:255.0/255.0 blue:255.0/255.0 alpha:1.0],

        UITextAttributeTextColor,

        [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.8],

        UITextAttributeTextShadowColor,

        [NSValue valueWithUIOffset:UIOffsetMake(0, -1)],

        UITextAttributeTextShadowOffset,

        [UIFont fontWithName:@"Arial-Bold" size:0.0],

        UITextAttributeFont,

        nil]]; ```

nav bar 隐藏 oc self.navigationController.navigationBar.hidden = YES;

将button作为bar button item添加到Navbar上

oc [sureButton setImage:sureImage forState:UIControlStateNormal]; [[UIBarButtonItem alloc] initWithCustomView:sureButton];

在nav bar 上添加多个按钮(ios7之前也是这种方式)

```oc UIBarButtonItem *shareItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self action:nil]; UIBarButtonItem *cameraItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCamera target:self action:nil];

NSArray *actionButtonItems = @[shareItem, cameraItem]; self.navigationItem.rightBarButtonItems = actionButtonItems; ```

要注意的是,uibarbuttonitem上图片的尺寸 是 2020 ,retina 是4040

UITabBar (extends UIView)

UITabBarItem设置图标和文字

UITabBarItem还有一个属性badgeValue(字符串类型),提醒用户有新消息。

设置tabbar背景图片 sh setBackgroundImage:

设置某个Item选中的效果图片 sh selectionIndicatorImage:

iOS6 会改变图标和文字的颜色,也会改变整个背景的着色;iOS只会改变图标和文字的着色。 sh setTintColor:

因此,在iOS6中最好不要使用setTintColor来设置tabbar背景颜色,而使用setBacgroundImage:

sh setSelectedImageTintColor:

修改tabbar 文字颜色 oc [[UITabBarItem appearance] setTitleTextAttributes:@{ UITextAttributeTextColor : [UIColor whiteColor] } forState:UIControlStateNormal]; [[UITabBarItem appearance] setTitleTextAttributes:@{ UITextAttributeTextColor : [UIColor whiteColor] } forState:UIControlStateHighlighted];

SegmentControl.tintColor 只在 segmentedControlStyle 为 UISegmentedControlStyleBar 时有效。

搜索栏和范围选择栏(scope bar)

注意:范围选择栏不能单独出现;必须依附在搜索栏下面出现

ViewController全屏幕布局

controller管理的view(xib中的view)

ios6, view从status bar下面开始布局 (0,20,320,548)

ios7,与status bar左上角坐标一样,(0,0,320,568)

view的size也变化了,ios6到ios7view的高度变大了20px,注意要设置好view 的subview的autoresingmask。因此,如果是在ios6中的布局,跑到ios7系统上,会有20px向上的偏移

引入下面3个属性:

extendedLayoutIncludesOpaqueBars

默认值NO,这个属性指定了当Bar使用了不透明图片时,视图是否延伸至Bar所在区域;因此,如果我们自定义了nav bar背景图片,view会从导航栏下面开始布局。

edgesForExtendedLayout

默认是UIRectEdgeAll,也就是全屏布局(iOS7中鼓励这样,这样可以透过半透明的bar看到一些模模糊糊的内容),如果设置为UIExtendedEdgeNone,view就不会延伸到bar的后面了

automaticallyAdjustsScrollViewInsets

默认值是YES,如果视图里面存在唯一一个UIScrollView或其子类View,,那么它会自动设置相应的内边距(如果有navbar的时候,这个内边距是64,这样scrollview可以占满屏幕,内容在64像素以下,不会被遮到,滑动scrollview,可以透过半透明效果看到scrollview上面的内容)

其他一些变化

iOS7中评分链接改变:http://stackoverflow.com/questions/18889395/app-review-link-not-working-anymore 形如:itms-apps://itunes.apple.com/app/idAPPpre_ID

加入iOS7兼容性代码

系统兼容常用的方式主要有下面2中方法:

  1. 直接提供2套UI,这种方法最为简单直接
  2. 加入适配性代码,比较适合控件间较少的布局,(事实上app很多页面就一个UITableView)

这里先搞清楚2个概念:编译时处理 VS 运行时处理

Base SDK设置会引导编译器使用该版本的SDK编译和构建应用,也就是如果basesdk选择ios7.0,则会选sdk 7.0来编译程序。这里有必要提下,如果你装了iOS6.0的sdk,basesdk选择iOS6.0运行在模拟器,xcode5任然会选择iOS7 sdk来编译你的项目,据SO上的讨论说是xcode的bug。

Deployment Target 控制着运行应用需要的最低操作系统版本

可以在编译时选择不同的代码编译: OC #ifdef __IPHONE_7_0 #else #endif 上面的条件编译还要依赖basesdk的设置,因此,最好还是用下面这种运行时判断的方式来处理iOS7兼容性的问题。

也可以在运行时根据版本选择不同的代码运行 ```OC #define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:(v) options:NSNumericSearch] != NSOrderedAscending)

if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(7.0)){}else{} ```

UI布局的经验分享

如果同时兼容iOS6,7,把原点定在(0,0)开始做布局,然后在iOS7中设置view的frame:

if(iOS7){ self.view.frame = CGRectMake(0,20,width,SCREEN_HEIGHT-20); }

这里对view有20px的压缩,如果使用autoresingmask做屏幕适配,应该注意view的subview的autoresingmask值的设置,以免出现诡异的问题。

iOS7反向兼容iOS6

在iOS6下将viewController.wantsFullScreenLayout=YES ,设置viewcontroller为全局布局。这时候iOS6和iOS7中ViewController的view的高度都等于屏幕高度。注意wantsFullScreenLayout方法已在iOS7中遗弃。

这样在iOS7中的布局可以无需任何更改就运行在iOS6的系统上。也就是你用iOS7布局,要反向兼容iOS6系统时,可以用这个方法。

带系统nav bar的iOS7兼容

当你的ViewController被UINavigationController 管理以后,wantsFullScreenLayout这一招来适配就失效了。

iOS6 中有navigation时,xib中的view的坐标是(0,64,320,504),而iOS7中是(0,0,320,568);view的size也变化了,ios6到ios7view的高度变大了64 points .

如果是在ios6中得布局,放到ios7 运行,发现view会被nav bar(此时的bar默认是半透明效果)挡到。解决办法是,在viewcontroller中: OC self.edgesForExtendedLayout = UIRectEdgeNone; 这样设置以后,iOS7中viewcontroller的view的frame为{(0,64),(320,504)},和iOS6中controller view的大小一样了。

对于底部有tabbar的情况,处理方式也一样。

下面的几种情况引起viewcontroller view frame 的变化

iOS7:

有Navbar是view的变化 加UIRectEdgeNone: viewDidLoad (0 0; 320 568) viewWillAppear (0 64; 320 504)

iOS6:

啥也没有 viewDidLoad (0,20,320,548)
viewWillAppear (0,20,320,548)

加self.wantsFullScreenLayout=YES viewDidLoad (0,20,320,548)
viewWillAppear (0,0,320,568)

有navbar (wantsFullScreenLayout 设置失效) viewDidLoad (0,20,320,548) viewWillAppear (0,0,320, 504)

viewDidLoad方法走完后,系统会根据是否wantsFullScreenLayout,是否有navbar,tabbar,来重新计算viewcontroller view的frame。

适配小工具

  1. ios6/ios7 Deltas 设置 在file inspector中禁用掉auto layout后,在size inspector中多了一个Deltas(增量)设置 ,来处理这种偏移问题,在ios6中设置deltas值,表示在ios7中得坐标+deltas增量。

  2. file inspector » view as ios7/ios6 Toggle between viewing app UI in iOS 7 and iOS 6.1 or earlier,可以看下在不同的系统上的UI样子

  3. 在xcode5中,preview不同版本上的效果:快捷键:option+command+enter 打开Assistant editor,然后选择右边的automatic->preview->MainIphone.storyboard(或xxx.xib) ,这个不仅可以看本通版本上的效果,还可以看不同屏幕分辨率上的效果。

Bee框架 iOS7UI适配

http://forum.bee-framework.com/index.php/forum/view/40