iOS 的 APP 如何适应 iPhone 5s/6/6Plus 三种屏幕的尺寸?

初代iphone
2007年,初代iphone发布,屏幕的宽高是 320 x 480 像素。下文也是按照宽度,高度的顺序排列。这个分辨率一直到iphone 3gs也保持不变。
那时编写ios的app(应用程序),只支持绝对定位。比如一个按钮(x, y, width, height) = (20, 30, 40, 50),就表示它的宽度是40像素,高度是50像素,放在(20, 20)像素的位置。
iphone 4
2010年,iphone 4发布,率先采用retina显示屏,在屏幕的物理尺寸不变的情况下,像素成倍增加,达到 640 x 960 像素。
这样就出现一个问题,怎么让原有的app运行在新的手机上面?iphone手机一个优势,就是有众多优秀的app,假如不兼容原有的app,就相当于放弃这个得来不易的优势,是很不明智的。
每当iphone的屏幕有所变化,比如iphone 3gs过渡到iphone 4, iphone 4过渡到iphone 5, iphone 5过渡到iphone 6,苹果公司都需要想办法来解决上述的兼容问题。
为了运行之前的app,引入一个新的概念point(点)。点这个概念在ios开发中十分重要,而非开发者很少关注。iphone 4屏幕尺寸继续保持320 x 480,不过单位并非是像素,而是点。
在iphone 3gs中,1个点等于1个像素。也就是说,点跟像素可以直接互换。
在iphone 4中,1个点等于2个像素。
iphone 4和iphone 3gs的屏幕尺寸实际上是一样的,都是3.5英寸。同样一个点,实际上看起来是一样的。只是iphone 4在单位英寸上像素更多,看起来更细腻。
开发ios的时候,使用点作为基本单位会更加方便。列表对比
这里的屏幕模式可以初步理解成,一个点等于多少个像素。2x,就是1个点等于2个像素。
总结一下单位
手机屏幕的物理长度,使用英寸作为单位。比如iphone 4屏幕是3.5英寸,iphone 5 是4英寸,iphone 6是4.7英寸,这里的数字是指手机屏幕对角线的物理长度。
屏幕像素,比如iphone 3gs屏幕是320 x 480像素,iphone 4是640 x 960像素,这里的像素可以想象成屏幕上真正用来显示颜色的发光小点。
点,开发app时候使用的单位,是一个虚拟的单位,并非实际存在的,因此点有时也叫虚拟点。点这个单位,用于屏蔽各个屏幕设备的不同,兼容以前的程序。
每英寸有多少个像素,称为ppi(pixel per inch)。我们可以简单算算,iphone 4是640 x 960像素,对角线就是1154像素,除以3.5英寸,应该是330ppi。而官方给出的数字是326ppi。当像素太密,超过300ppi的时候,人眼也就不能区分出每个像素。因此iphone 4的屏幕叫作retina显示屏。retina在英文中,是视网膜的意思。
iphone 4之后(x, y, width, height) = (20, 30, 40, 50),就表示高度为40个点,宽度为50个点,放在(20, 20)个点的位置。这种处理方法,将之前以像素作为单位自动转换成以点作为单位,使得iphone 3gs的应用程序,不用修改也可运行在iphone 4上面。
文字,颜色等是矢量数据,放大不会失真。原有的iphone 3gs程序,在iphone 4上面运行,文字显示也十分清晰。
而图片并非矢量数据,处理方式有所不同。假设图片 example.png,大小为 30 x 40像素(这里的单位是像素,数字图片的单位通常都为像素)。当这张example.png在iphone 3gs和iphone 4中使用时候,都占据屏幕上30 x 40个点。而因为iphone 4中1个点等于2个像素,也就是30 x 40像素的图片,占据了60 x 80像素的屏幕,因此这图片在iphone 4中看起来就会模糊。
开发的时候,为使得图片清晰,需要进行图片适配。这时需要准备两张内容相同的图片,放在同一目录下。
example.png // 30 x 40像素 example@2x.png // 60 x 80像素当程序中使用example.png的时候,会根据屏幕模式自动选择对应的图片。屏幕1x模式,就会选择example.png, 2x模式就会优先选择example@2x.png,假如example@2x.png不存在,就选择example.png。
图片跟屏幕一样,也有1x模式,2x模式。在iphone 6 plus中,还出现3x模式,原理是一样的。
当iphone 4选中example@2x.png的图片,就会生成一张大小为30 x 40个点,2x模式的图片。这个时候,图片看起来就会很清晰了。而没有适配的旧程序,example@2x.png不存在,就选中example.png,生成大小为30 x 40个点,1x模式的图片,看起来比较模糊。但它们占据的屏幕点数是一样的。
iphone 5
2012年,苹果发布iphone 5。我们将所有机型对比,依然采用点作为单位。
跟iphone 4做比较, iphone 5的宽度保持不变。高度增加568 – 480 = 88个点。
在ios开发中,44这个数字比较特殊。ios界面指南写着,人类的手指有一定大小,点击区域低于44个点的时候,就难以点中。44的两倍就是88。
当原有程序没有适配iphone 5的时候,也可以正常运行,但多出来的88个点将会将会被自动均分为上下两部分,使得上下出现黑边。我找不到好看的图片。
那么怎样才能告诉ios系统,应用程序已经适配了iphone 5呢?在这里,我们先扯开一下,谈一下启动图片。
点击主屏幕的图标,进入app的时候,会立即显示一张图片,这张图片就是启动图片(launch image)。app在正式启动的时需要做一些初始化处理,这通常比较费时。先出现启动图片,可以使用户觉得系统立即有响应,减少等待的焦虑感。
每个机型,比如同时支持iphone和ipad的程序,需要分别为iphone跟ipad指定启动图片。当旧的iphone 4的程序,运行在iphone 5上面,没有iphone 5的启动图片,就采用兼容模式,上下留黑边。当为iphone 5指定了新的启动图片,系统就认为这个应用程序是已经适配了iphone 5的,上下就不会留黑边了。下面是微信启动图片,应该都很熟悉了。
微信启动图片中出现的那个地球,叫蓝色弹珠(the blue marble),是在1972年12月7日由阿波罗17号太空船的船员所拍摄的。这张照片当年很震撼,是普通人第一次可以通过照片直接看到地球的全貌。见问题为什么微信启动界面的地球图片没有转到中国这部分?这是否有损用户体验?
微信的启动图,为适配iphone 5,相比与iphone 4, 很明显狭长了。
典型iphone应用程序(游戏除外),很多是上面一个导航栏,下面一个工具栏或者标签栏, 中间一大块用于显示的内容区。iphone 5拉长了,对于程序的适配,也不算麻烦,内容区的内容基本是动态生成的。适配时候可以简单上下不变,中间的内容区拉长就行了。注意,导航栏和工具栏的高度也是44个点。下面是同一程序,在iphone 4跟iphone 5的对比。
autolayout
到了这个时候,传统绝对定位的弱点就显露出来了。这时iphone按照点作为单位,已经出现了两种不同尺寸的屏幕,算上ipad, 就有3种尺寸(有些app可以同时兼容iphone和ipad,称为universal)。
从ios 6系统发布后,ios开发中可以采用一种autolayout的技术。autolayout就像网页一样,指定view,button,text之间的相对位置,比如靠左多少,靠右多少,居中多少等等。举个例子,像下面的简单布局。
假设左上角的区域为view1, 右上角的区域为view2, 下面的区域为view3。autolayout会说:
view1.left = 20 // view1的左边距离边界20个点 view1.top = 20 // view1的上边距离边界20个点 view2.right = 20 // view2的右边距离边界20个点 view2.top = 20 // view2的上边距离边界20个点 view2.left = view1.left + 20 // view2的左边距离view1右边20个点 view2.width = view1.width // view1的宽度等于view2的宽度 view2.height = view1.height // view1高度等于view2高度 view3.left = view1.left // view3的跟view1左对齐 view3.right = view2.right // view3跟view2右对齐 view3.top = view1.bottom + 20 // view3的上边距离view1下边20个点 view3.bottom = 20 // view3下边距离边界20个点 view3.height = view1.height // view3高度等于view1高度指定上面的约束条件后,autolayout就会自动算出对应的布局。上面我写得比较