iOS 屏幕适配~~整理了一些屏幕适配的东西 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
tunnyios
V2EX    iOS

iOS 屏幕适配~~整理了一些屏幕适配的东西

  •  1
     
  •   tunnyios 2016-05-21 17:10:19 +08:00 8909 次点击
    这是一个创建于 3430 天前的主题,其中的信息可能已经有所发展或是发生改变。

    欢迎关注我的 Blog tunnycoder.com

    整理了一些 iOS 屏幕适配的东西

    自从 Apple 出了 4.7 寸和 5.5 寸的 iphone 后,在 iOS 开发中, 屏幕适配也成为了一项很重要的工作。(PS:之前一直吐槽安卓各种屏幕适配好蛋疼,后来发现出来混总是要还的。)还好苹果公司也在为这条适配之路更走,不断的改进着~本文记录了一些屏幕适配过程中的一些问题。

    4s 、 5/5s 、 6/6s 、 6p/6sp 的参数以及适配的参考基准建议

    | 机型 | 屏幕宽高(point) | 渲染像素(pixel) | 物理像素(pixel) | 屏幕对角线长度(英寸) | 屏幕模式 | | -------- |:---------:|:---------:|:---------:|:---------:|:---------:| ------:| |iPhone 2G/3G/3GS|320 * 480| 320 * 480| 320 * 480| 3.5(163PPI)| 1x| |iPhone 4/4s| 320 * 480| 640 * 960| 640 * 960| 3.5 (326PPI)| 2x| |iPhone 5/5s| 320 * 568| 640 * 1136| 640 * 1136| 4 (326PPI)| 2x| |iPhone 6/6s| 375 * 667| 750 * 1334| 750 * 1334| 4.7 (326PPI)| 2x| |iPhone 6Plus/6sPlus| 414 * 736| 1242 * 2208| 1080 * 1920| 5.5 (401PPI)| 3x| 设计和开发时一般选用 iphone6 作为基准尺寸,原因如下:

    1. 从中间尺寸向上和向下适配的时候界面调整的幅度最小。如果直接以 414pt 作为基准,那么适配到 320pt 的时候可能就会出现视觉比例失调。
    2. iPhone 6 plus 有两种显示模式,标准模式分辨率为 1242x2208 ,放大模式分辨率为 1125x2001 (即 iPhone 6 的 1.5 倍)。很多情况下这两种尺寸可以用 1.5 倍直接等比适配。如果 UI 设计师可以做两套,一般情况下都是使用 375pt 作为基准设计一套(用来切 @2x 图),然后再等比放大 1.5 倍,生成 1125px 的设计稿(用来切 @3x 图)。
    3. 1242x2208 这个奇葩的分辨率,不便于记忆和计算栅格。

    以 iphone6 作为基准尺寸,适配原则:文字流式,控件弹性,图片等比缩放。

    App 设计的几个技巧

    • 非矢量素材,就可以做尺寸最大的,之后再进行缩小。比如需要兼容 3x 的屏幕,就直接做最高那种图片。
    • 假如是那种导航栏,工具栏之类的背景图,需要横跨整个屏幕。可以只切一小块,让程序拉伸,拉伸方式是保持两边的像素不动,只拉伸最中间的一列像素。需要拉伸的话,横方向就不要出现一些渐变色。
    • 按钮的点击区域,不应该少于 44 像素,就算按钮的图片看起来比较小,也应该使得点按钮周围的透明区也有反应。

    启动高分辨率方法

    以前的旧工程跑 iphone6 和 iphone6plus 时,默认是「兼容模式」即系统会简单的把内容等比放大,但效果粗糙。此时程序中获取到的设备尺寸还是和 iphone5s 一个尺寸 320pt 。

    启动高分辨率模式的方法:

    • 在项目中添加 Launch Screen File Lanuch Screen 是 xcode6 和 iOS8 新加的功能,它用一个 xib 或者 storyboard 作为启动画面。 iOS 在旧版系统中启动时,该属性会被自动忽略,不会造成异常。

    补充启动动画

    iOS 启动动画的方式有两种:启动图和布局文件。 Xcode 6 是 LaunchScreen.xib ,到 Xcode 7 变成了 LaunchScreen.storyboard ,无可厚非,两者本质都是一样的。

    使用布局文件实现启动动画也很简单:获取LaunchScreen.storyboard 里的 ViewController,在把View 提取出来加到UIWindow显示做动画即可。这种方式的好处就是,获取大小就是屏幕的大小,而且只要你把不同屏幕的布局搞定了,系统会帮你生成好加在的启动页,这样就免去了判断和从新设置大小的麻烦,这样才是真适配嘛~

    //设置启动动画并跳转 self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; [self.window makeKeyAndVisible]; UIViewController* myvc = [[UIViewController alloc] initWithNibName:nil bundle:nil]; self.window.rootViewCOntroller= myvc; UIViewController *viewCOntroller= [[UIStoryboard storyboardWithName:@"Launch Screen" bundle:nil] instantiateViewControllerWithIdentifier:@"LaunchScreen"]; self.lunchView = viewController.view; [self.window addSubview:self.lunchView]; self.imageV = [[UIImageView alloc] initWithFrame:[UIScreen mainScreen].bounds]; self.imageV.image = [UIImage imageNamed:@"default0"]; self.timerIndex = 0; self.timer = [NSTimer scheduledTimerWithTimeInterval:0.2f target:self selector:@selector(updateImage:) userInfo:nil repeats:YES]; [self.lunchView addSubview:self.imageV]; [self.window bringSubviewToFront:self.lunchView]; 

    PS: 注意升级 Xcode 7 之后 ios 9 一启动程序就报错Assertion failure in -[UIApplication _runWithMainScene:transitionContext:completion:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3505.16/UIApplication.m:3294

    原因是:新的 SDK 不允许在设置rootViewController之前做过于复杂的操作。解决办法: 先设置个rootVIewController之后重新赋值。

    Autolayout 与 size Classes 适配

    Autolayout 是在 xcode5 之后流行起来的,解决了 Autoresizing 在 storyboard 中,无法实现兄弟控件的布局的问题。 Autolayout 的核心是参照和约束。用相对位置解决问题。

    Autolayout 可以动态的修改约束,只需要将对应的约束拖到对应的 view 或者对应的 Controller 中,进行动态修改,并添加一句 [添加了约束的 view layoutIfNeeded]; 就会在下一个消息循环里调用里刷新屏幕的时候调用updateViewConstraints方法。 Autolayout 添加动画也是这样做的。

    // 1. 修改约束 xxxxxxxx // 2.执行动画 [UIView animateWithDuration:5 animations:^ { // 让 view 上的约束执行动画 [self.view layoutIfNeeded]; }]; 

    注: iOS 建议:忘掉 Frame ,使用 Autolayout, 使用比例来固定尺寸而非具体的尺寸大小;相同级别的控件他们的约束在父控件去找

    SizeClass 实现屏幕多样化,界面大统一。

    1. 仅仅是对屏幕进行了分类,排布 UI 元素还需要 autolayout
    2. 不再有横竖屏概念,只有屏幕尺寸的概念,无法单独区分出 5.5 寸竖屏
    3. 不再有具体尺寸的区别,只有抽象尺寸的概念
    4. 把宽度和高度分为三种情况:Compact(紧凑) Any(任意) Regular(正常)

    SizeClass 各模式下的适配情况:

    • 宽高任意( WAHA ):任意设备
    • 宽任意高正常(WAHR): 3.5 寸竖屏, 4 寸竖屏, 4.7 寸竖屏, 5.5 寸竖屏, iPad 竖屏、 iPad 横屏
    • 宽任意高紧凑(WAHC): 3.5 寸横屏 , 4 寸横屏, 4.7 寸横屏, 5.5 寸横屏
    • 宽正常高任意(WRHA): 5.5 寸横屏, iPad 竖屏、 iPad 横屏
    • 宽正常高正常(WRHR): iPad 竖屏、 iPad 横屏
    • 宽正常高紧凑(WRHC): 5.5 寸横屏
    • 宽紧凑高任意(WCHA): 3.5 寸竖屏、 3.5 寸横屏, 4 寸竖屏、 4 寸横屏, 4.7 寸竖屏、 4.7 寸横屏, 5.5 寸竖屏
    • 宽紧凑高正常(WCHR): 3.5 寸竖屏, 4 寸竖屏, 4.7 寸竖屏, 5.5 寸竖屏
    • 宽紧凑高紧凑(WCHC): 3.5 寸横屏, 4 寸横屏, 4.7 寸横屏

    SizeClass 的其他用途:

    通过 Image Asset 为不同的 SizeClass 配置不同的图片

    Label 的 FontSize 根据不同的 SizeClass 设置不同的字号

    SizeClass 关于代码中判断屏幕旋转问题

    • Apple 在 iOS 8 中引入了一个新的类,UITraitCollection。这个类封装了像水平和竖直方向的 Size Class 等信息。 iOS 8 的 UIKit 中大多数 UI 的基础类 (包括 UIScreenUIWindowUIViewControllerUIView) 都实现了 UITraitEnvironment 这个接口,通过其中的 traitCollection 这个属性,我们可以拿到对应的 UITraitCollection 对象,从而得知当前的 Size Class,并进一步确定界面的布局。

    注:如果项目要区分横竖屏幕、和支持 ipad 以及 ipad 横竖屏幕,应该一开始就提前沟通好,然后选择合适的 SizeClass 来进行操作,否则最后画好了之后再考虑横竖屏幕会很蛋疼(但也不是不能做)。

    Demo 就 Autolayout 和 SizeClass 写了一个 Demo,里面涉及了一些基本的使用,有兴趣的小伙伴可以下载看看

    Demo 下载

    2 条回复    2016-05-22 11:21:28 +08:00
    ins
        1
    ins  
       2016-05-22 07:59:22 +08:00
    这个好..很有用
    xiaoc19
        2
    xiaoc19 &nbs;
       2016-05-22 11:21:28 +08:00
    Autolayout 有些约束想的头疼
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2575 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 24ms UTC 05:00 PVG 13:00 LAX 22:00 JFK 01:00
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86