iPhone屏幕適配,歷史及現(xiàn)狀
初代 iPhone
2007 年,初代 iPhone 發(fā)布,屏幕的寬高是 320 x 480 像素。下文也是按照寬度,高度的順序排列。這個分辨率一直到 iPhone 3GS 也保持不變。
那時編寫 iOS 的 App(應用程序),只支持絕對定位。比如一個按鈕(x, y, width, height) = (20, 30, 40, 50),就表示它的寬度是 40 像素,高度是 50 像素,放在(20, 20)像素的位置。
iPhone 4
2010 年,iPhone 4 發(fā)布,率先采用 Retina 顯示屏,在屏幕的物理尺寸不變的情況下,像素成倍增加,達到 640 x 960 像素。
這樣就出現(xiàn)一個問題,怎么讓原有的 App 運行在新的手機上面?iPhone 手機一個優(yōu)勢,就是有眾多優(yōu)秀的 App,假如不兼容原有的 App,就相當于放棄這個得來不易的優(yōu)勢,是很不明智的。
每當 iPhone 的屏幕有所變化,比如 iPhone 3GS 過渡到 iPhone 4, iPhone 4 過渡到 iPhone 5, iPhone 5 過渡到 iPhone 6,蘋果公司都需要想辦法來解決上述的兼容問題。
為了運行之前的 App,引入一個新的概念 point(點)。點這個概念在 iOS 開發(fā)中十分重要,而實際用戶很少關(guān)注。iPhone 4 屏幕尺寸繼續(xù)保持 320 x 480,不過單位并非是像素,而是點。
-
在 iPhone 3GS 中,1 個點等于 1 個像素。也就是說,點跟像素可以直接互換。
-
在 iPhone 4 中,1 個點等于 2 個像素。
這篇文章中,我將點和像素當成一維的長度單位,而非二維的面積單位,這樣對于我來說更自然些,因此 1 個點等于 2 個像素。別的文章中可能會說 1 個點等于 4 個像素,其實是指 1 個點占據(jù)了 4 個像素的面積,這樣也沒有說錯,注意上下文語境。
iPhone 4 和 iPhone 3GS 的屏幕尺寸實際上是一樣的,都是 3.5 英寸。同樣一個點,實際尺寸看起來是一樣的。只是 iPhone 4 在單位英寸上像素更多,看起來更細膩。
開發(fā) iOS 的時候,使用點作為基本單位會更加方便,列表對比:
這里的屏幕模式可以初步理解成,一個點等于多少個像素。2x,就是 1 個點等于 2 個像素。
總結(jié)一下單位
-
手機屏幕的物理長度,使用英寸作為單位。比如 iPhone 4 屏幕是 3.5 英寸,iPhone 5 是 4 英寸,iphone 6 是 4.7 英寸,這里的數(shù)字是指手機屏幕對角線的物理長度。
-
屏幕像素,比如 iPhone 3GS 屏幕是 320 x 480 像素,iPhone 4 是 640 x 960 像素,這里的像素可以想象成屏幕上真正用來顯示顏色的發(fā)光小點。
-
點,開發(fā) App 時候使用的單位,是一個虛擬的單位,并非實際存在的,因此點有時也叫虛擬點。點這個單位,用于屏蔽各個屏幕設(shè)備的不同,兼容以前的程序。
每 英寸有多少個像素,稱為 ppi(pixel per inch)。iPhone 4 的屏幕是 640 x 960 像素,3.5 英寸,我們沒有寬高的實際尺寸,就按照對角線來粗略計算它的 ppi。將像素當做長度單位,根據(jù)勾股定理,對角線就是 1154 像素。屏幕對角線的實際長度為 3.5 英寸,也就是 1154 像素除以 3.5 英寸,得出 330ppi。而官方給出的數(shù)字是 326ppi。當像素太密,超過 300ppi 的時候,人眼也就不能區(qū)分出每個像素。因此 iPhone 4 的屏幕叫作 Retina 顯示屏。Retina 在英文中,是視網(wǎng)膜的意思。
iPhone 4 之后(x, y, width, height) = (20, 30, 40, 50),就表示高度為 40 個點,寬度為 50 個點,放在(20, 20)個點的位置。這種處理方法,將之前以像素作為單位自動轉(zhuǎn)換成以點作為單位,使得 iPhone 3GS 的應用程序,不用修改也可運行在 iPhone 4 上面。
文字,顏色等是矢量數(shù)據(jù),放大不會失真。原有的 iPhone 3GS 程序,在 iPhone 4 上面運行,文字顯示也十分清晰。
而 圖片并非矢量數(shù)據(jù),處理方式有所不同。假設(shè)圖片 example.png,大小為 30 x 40 像素(這里的單位是像素,數(shù)字圖片的單位通常都為像素)。當這張 example.png 在 iPhone 3GS 和 iPhone 4 中使用時候,都占據(jù)屏幕上 30 x 40 個點。而因為 iPhone 4 中 1 個點等于 2 個像素,也就是 30 x 40 像素的圖片,占據(jù)了 60 x 80 像素的屏幕,因此這圖片在 iPhone 4 中看起來就會模糊。
開發(fā)的時候,為使得圖片清晰,需要進行圖片適配。這時需要準備兩張內(nèi)容相同的圖片,放在同一目錄下。
example.png // 30 x 40 像素
example@2x.png // 60 x 80 像素
當 程序中使用 example.png 的時候,會根據(jù)屏幕模式自動選擇對應的圖片。屏幕 1x 模式,就會選擇 example.png, 2x 模式就會優(yōu)先選擇 example@2x.png,假如 example@2x.png 不存在,就選擇 example.png。
圖片跟屏幕一樣,也有 1x 模式,2x 模式。在 iPhone 6 Plus 中,還出現(xiàn) 3x 模式,原理是一樣的。
當 iPhone 4 選中 example@2x.png 的圖片,就會生成一張大小為 30 x 40 個點,2x 模式的圖片。這個時候,圖片看起來就會很清晰了。而沒有適配的舊程序,example@2x.png 不存在,就選中 example.png,生成大小為 30 x 40 個點,1x 模式的圖片,看起來比較模糊。但它們占據(jù)的屏幕點數(shù)是一樣的。
iPhone 5
2012 年,蘋果發(fā)布 iPhone 5。我們將所有機型對比,依然采用點作為單位。
跟 iPhone 4 做比較, iPhone 5 的寬度保持不變。高度增加 568 - 480 = 88 個點。
在 iOS 開發(fā)中,44 這個數(shù)字比較特殊。iOS 界面指南寫著,人類的手指有一定大小,點擊區(qū)域低于 44 個點的時候,就難以點中。44 的兩倍就是 88。
當原有程序沒有適配 iPhone 5 的時候,也可以正常運行,但多出來的 88 個點將會將會被自動均分為上下兩部分,使得上下出現(xiàn)黑邊。我找不到好看的圖片。
那么怎樣才能告訴 iOS 系統(tǒng),應用程序已經(jīng)適配了 iPhone 5 呢?在這里,我們先扯開一下,談一下啟動圖片。
點擊主屏幕的圖標,進入 App 的時候,會立即顯示一張圖片,這張圖片就是啟動圖片(Launch Image)。App 在正式啟動的時需要做一些初始化處理,這通常比較費時。先出現(xiàn)啟動圖片,可以使用戶覺得系統(tǒng)立即有響應,減少等待的焦慮感。
每 個機型,比如同時支持 iPhone 和 iPad 的程序,需要分別為 iPhone 跟 iPad 指定啟動圖片。當舊的 iPhone 4 的程序,運行在 iPhone 5 上面,沒有 iPhone 5 的啟動圖片,就采用兼容模式,上下留黑邊。當為 iPhone 5 指定了新的啟動圖片,系統(tǒng)就認為這個應用程序是已經(jīng)適配了 iPhone 5 的,上下就不會留黑邊了。下面是微信啟動圖片,應該都很熟悉了。
微信啟動圖片中出現(xiàn)的那個地球,叫藍色彈珠(The Blue Marble),是在 1972 年 12 月 7 日由阿波羅 17 號太空船的船員所拍攝的。這張照片當年很震撼,是普通人***次可以通過照片直接看到地球的全貌。見問題為什么微信啟動界面的地球圖片沒有轉(zhuǎn)到中國這部分?這是否有損用戶體驗?
微信的啟動圖,為適配 iPhone 5,相比與 iPhone 4, 很明顯狹長了。
典 型 iPhone 應用程序(游戲除外),很多是上面一個導航欄,下面一個工具欄或者標簽欄, 中間一大塊用于顯示的內(nèi)容區(qū)。iPhone 5 拉長了,對于程序的適配,也不算麻煩,內(nèi)容區(qū)的內(nèi)容基本是動態(tài)生成的。適配時候可以簡單上下不變,中間的內(nèi)容區(qū)拉長就行了。注意,導航欄和工具欄的高度也 是 44 個點。下面是同一程序,在 iPhone 4 跟 iPhone 5 的對比。
AutoLayout
到了這個時候,傳統(tǒng)絕對定位的弱點就顯露出來了。這時 iPhone 按照點作為單位,已經(jīng)出現(xiàn)了兩種不同尺寸的屏幕,算上 iPad, 就有 3 種尺寸(有些 App 可以同時兼容 iPhone 和 iPad,稱為 Universal)。
從iOS 6系統(tǒng)發(fā)布后,iOS開發(fā)中可以采用一種 AutoLayout 的技術(shù)。AutoLayout 就像網(wǎng)頁一樣,指定 View,Button,Text 之間的相對位置,比如靠左多少,靠右多少,居中多少等等。舉個例子,像下面的簡單布局。
假設(shè)左上角的區(qū)域為 view1, 右上角的區(qū)域為 view2, 下面的區(qū)域為 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.right + 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 就會自動算出對應的布局。上面我寫得比較繁瑣,事實上很多操作都是可以使用鼠標拖拉來指定的,并不一定需要使用代碼。但就算用代碼,也有簡寫的方法。下面是在 xib 中,拖拉鼠標指定約束時的界面。
而絕對定位,會直接說
- view1.frame = (x1, y1, width1, height1)
- view2.frame = (x2, y2, width2, height2)
- view3.frame = (x3, y3, width3, height3)
絕對定位并非指定約束條件,而是開發(fā)者自己來精確指定 View,Button, Text 等的實際坐標大小。
對于一個屏幕,絕對定位可能跟 AutoLayout 的區(qū)別不算大,甚至絕對定位會更方便些。但當需要同時適配多個屏幕,AutoLayout 根本不需要更改。而絕對定位就需要根據(jù)屏幕大小,一個個算出來。比如橫屏,在 AutoLayout 下面,就自動變成:
這里不過是 3 個控件的布局,當出現(xiàn)的控件數(shù)越多,屏幕尺寸越多,AutoLayout 的優(yōu)勢就顯露出來了。另外 AutoLayout 有個好處是容易支持多語言,不同語言下,同一個意思文字的長度是不同的,使用 AutoLayout 也可以自動適配。
在 iOS 6 的時候,AutoLayout 還比較少人使用,當時屏幕尺寸還比較少。iOS 7 的時候,就開始很多人使用了。而到現(xiàn)在 iOS 8 了, 更加上 iPhone 6, iPhone 6 Plus 需要適配,AutoLayout 大勢所趨,不用不行了。
iPhone 6和iPhone 6 Plus
2014 年,iPhone 6和iPhone 6 Plus 發(fā)布后,情況又有新的變化。再次比較所有 iPhone 機型。
屏幕尺寸再度分裂。但是我們比較 iPhone 5 跟 iPhone 6 的寬高比例。
可以看出,iPhone 6 跟 iPhone 5 雖然屏幕尺寸改變了,但是它們的比例是不變的。都是 9 ÷ 16 = 0.5625 的屏幕。
當舊的 iPhone 5 程序運行在 iPhone 6 上面,假如沒有經(jīng)過適配,舊程序自動等比放大,鋪滿新手機,舊程序也可以正常運行。這種方案可算是自動適配。但因為舊程序拉伸了,整體看起來有點虛,也不能更好利用大屏空間。
當 需要開發(fā)者手動適配的時候,跟 iPhone 4 過渡到 iPhone 5 一樣,在新程序中,指定一張新的啟動圖片。當指定了啟動圖,屏幕分辨率就已經(jīng)變成應有的大小,這時候利用 AutoLayout 進行布局,同一份代碼,就可以支持多個機型。新手機的屏幕更大,有更多的虛擬點,可以顯示更多的內(nèi)容。
值得注意一點是,iPhone 6 Plus。它的寬高是 414 × 736 個點,3x 模式,理想上來說,應該有 1242 × 2208 像素。但 iPhone 6 Plus 的實際像素是 1080 × 1920,是比理想值要少一點的。iPhone 6 Plus 的處理方式是將程序整體稍微縮小一點。分辨率很高,這點區(qū)別,實際上也看不出來。
那為什么需要這樣做呢?上面表格中 iPhone 6, iPhone 6 Plus 屏幕寬高的邏輯點的數(shù)字是怎么來的?下面我猜測一下原因,但不能證實。
先 看 iPhone 6,這個比較簡單。iPhone 6 的屏幕寬高比例跟 iPhone 5 一樣,使用對角線來計算,就是放大了 4.7 ÷ 4 = 1.175 倍。用這個數(shù)字,乘以 iPhone 5 的 320 x 568 個點,忽略誤差,差不多就是 iPhone 6 屏幕的 375 x 667 個點。這里需要注意,屏幕寬高比例一樣,才能使用對角線來計算。
按照上面的方式來計算 iPhone 6 Plus, 應該是得到 440 x 781 個點,實際上卻是 414 × 736 個點。這里我猜測是因為,iPhone 6 Plus 屏幕明顯更大,相同尺寸的點放在大的屏幕上面,會使得人感覺尺寸變小,所以就將每個點的實際尺寸放大一些,從而得到更少的點數(shù)目。人眼看東西會有種錯覺, 并非是孤立的看的,而是跟周圍的環(huán)境作比較。
確定了點數(shù)目之后,再確定了像素 1080 × 1920(很多高清電視就是這個尺寸),應該是 1080/414=2.6x,但 2.6x 這個數(shù)字開發(fā)就太麻煩了,就按照 3x 來處理。其實假如像素達到 1242 × 2208,3x 下也可以精確到 1:1, 這樣會更好。但現(xiàn)今的技術(shù)在考慮電池,處理器,屏幕尺寸等綜合因素下,很可能達不到這樣的細膩程度。
上述只是猜測,我相信那些手機參數(shù)是經(jīng)過反復考慮再確定的。iPhone 6 Plus 這個處于手機跟平板中間地帶的產(chǎn)物經(jīng)過不少特殊處理。
由分析可以看到,慢慢的為了適配多個機型,程序的啟動圖片也逐漸增多,為解決這個問題。iOS 8 之后,可以使用 xib 來搭建啟動界面,這樣就可以同一個啟動界面,適配多個機型,減少啟動圖片占用的空間。
建議
以后的應用程序,都使用 AutoLayout, 不要再用絕對定位。
使用類似網(wǎng)頁的方式來設(shè)計界面。設(shè) 計師好,程序員也好,盡量使用點這個單位進行思考,而不要使用像素。比如,你需要做 44 x 66 個點的按鈕,2x 模式,就乘以 2, 3x 模式就乘以 3。這樣的思考方式可以大致估計到真實的物理長度。44 個點,就是手機上導航欄,工具欄的高度。假如用像素思考,容易使得做出的圖片過大或者過小。