iOS 的 APP 在系統中如何適應 iPhone 5s/6/6 Plus 三種屏幕的尺寸

鏈接:https://www.zhihu.com/question/25421514/answer/31623

iPhone屏幕適配,歷史及現狀

初代iPhone

2007年,初代iPhone發布,屏幕的寬高是 320 x 480 像素。下文也是按照寬度,高度的順序排列。這個分辨率一直到iPhone 3GS也保持不變。

那時編寫iOS的App(應用程序),只支持絕對定位。比如一個按鈕(x, y, width, height) = (20, 30, 40, 50),就表示它的寬度是40像素,高度是50像素,放在(20, 30)像素的位置。

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,不過單位并非是像素,而是點。

  1. 在iPhone 3GS中,1個點等于1個像素。也就是說,點跟像素可以直接互換。
  2. 在iPhone 4中,1個點等于2個像素。

這篇文章中,我將點和像素當成一維的長度單位,而非二維的面積單位,這樣對于我來說更自然些,因此1個點等于2個像素。別的文章中可能會說1個點等于4個像素,其實是指1個點占據了4個像素的面積,這樣也沒有說錯,注意上下文語境。

iPhone 4和iPhone 3GS的屏幕尺寸實際上是一樣的,都是3.5英寸。同樣一個點,實際尺寸看起來是一樣的。只是iPhone 4在單位英寸上像素更多,看起來更細膩。

開發iOS的時候,使用點作為基本單位會更加方便。列表對比

這里的屏幕模式可以初步理解成,一個點等于多少個像素。2x,就是1個點等于2個像素。

總結一下單位:

  1. 手機屏幕的物理長度,使用英寸作為單位。比如iPhone 4屏幕是3.5英寸,iPhone 5 是4英寸,iphone 6是4.7英寸,這里的數字是指手機屏幕對角線的物理長度。
  2. 屏幕像素,比如iPhone 3GS屏幕是320 x 480像素,iPhone 4是640 x 960像素,這里的像素可以想象成屏幕上真正用來顯示顏色的發光小點。
  3. 點,開發App時候使用的單位,是一個虛擬的單位,并非實際存在的,因此點有時也叫虛擬點。點這個單位,用于屏蔽各個屏幕設備的不同,兼容以前的程序。

每英寸有多少個像素,稱為ppi(pixel per inch)。iPhone 4的屏幕是640 x 960像素,3.5英寸,我們沒有寬高的實際尺寸,就按照對角線來粗略計算它的ppi。將像素當做長度單位,根據勾股定理,對角線就是1154像素。屏幕對角線的實際長度為3.5英寸,也就是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.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)

絕對定位并非指定約束條件,而是開發者自己來精確指定View,Button, Text等的實際坐標大小。

對于一個屏幕,絕對定位可能跟AutoLayout的區別不算大,甚至絕對定位會更方便些。但當需要同時適配多個屏幕,AutoLayout根本不需要更改。而絕對定位就需要根據屏幕大小,一個個算出來。比如橫屏,在AutoLayout下面,就自動變成。

這里不過是3個控件的布局,當出現的控件數越多,屏幕尺寸越多,AutoLayout的優勢就顯露出來了。另外AutoLayout有個好處是容易支持多語言,不同語言下,同一個意思文字的長度是不同的,使用AutoLayout也可以自動適配。

在iOS 6的時候,AutoLayout還比較少人使用,當時屏幕尺寸還比較少。iOS 7的時候,就開始很多人使用了。而到現在iOS 8了, 更加上iPhone 6, iPhone 6 Plus需要適配,AutoLayout大勢所趨,不用不行了。

iPhone 6, iPhone 6 Plus

2014年,iPhone 6, iPhone 6 Plus發布后,情況又有新的變化。再次比較所有iPhone機型。


屏幕尺寸再度分裂。但是我們比較iPhone 5 跟 iPhone 6的寬高比例。

可以看出,iPhone 6跟iPhone 5雖然屏幕尺寸改變了,但是它們的比例是不變的。都是 9 ÷ 16 = 0.5625 的屏幕。

當舊的iPhone 5程序運行在iPhone 6上面,假如沒有經過適配。舊程序自動等比放大,鋪滿新手機,舊程序也可以正常運行。這種方案可算是自動適配。但因為舊程序拉伸了,整體看起來有點虛,也不能更好利用大屏空間。

當需要開發者手動適配的時候,跟iPhone 4過渡到iPhone 5一樣,在新程序中,指定一張新的啟動圖片。當指定了啟動圖,屏幕分辨率就已經變成應有的大小,這時候利用AutoLayout進行布局,同一份代碼,就可以支持多個機型。新手機的屏幕更大,有更多的虛擬點,可以顯示更多的內容。

值得注意一點是,iPhone 6 Plus。它的寬高是414 × 736個點,3x模式,理想上來說,應該有1242 × 2208像素。但iPhone 6 Plus的實際像素是 1080 × 1920,是比理想值要少一點的。iPhone 6 Plus的處理方式是將程序整體稍微縮小一點。分辨率很高,這點區別,實際上也看不出來。

那為什么需要這樣做呢?上面表格中iPhone 6, iPhone 6 Plus屏幕寬高的邏輯點的數字是怎么來的?下面我猜測一下原因,但不能證實。

先看iPhone 6,這個比較簡單。iPhone 6的屏幕寬高比例跟iPhone 5一樣,使用對角線來計算,就是放大了4.7 ÷ 4 = 1.175倍。用這個數字,乘以iPhone 5的320 x 568個點,忽略誤差,差不多就是iPhone 6屏幕的375 x 667個點。這里需要注意,屏幕寬高比例一樣,才能使用對角線來計算。

按照上面的方式來計算iPhone 6 Plus, 應該是得到440 x 781個點,實際上卻是414 × 736個點。這里我猜測是因為,iPhone 6 Plus屏幕明顯更大,相同尺寸的點放在大的屏幕上面,會使得人感覺尺寸變小,所以就將每個點的實際尺寸放大一些,從而得到更少的點數目。人眼看東西會有種錯覺,并非是孤立的看的,而是跟周圍的環境作比較。

確定了點數目之后,再確定了像素1080 × 1920(很多高清電視就是這個尺寸),應該是1080/414=2.6x,但2.6x這個數字開發就太麻煩了,就按照3x來處理。其實假如像素達到1242 × 2208,3x下也可以精確到1:1, 這樣會更好。但現今的技術在考慮電池,處理器,屏幕尺寸等綜合因素下,很可能達不到這樣的細膩程度。

上述只是猜測,我相信那些手機參數是經過反復考慮再確定的。iPhone 6 Plus這個處于手機跟平板中間地帶的產物經過不少特殊處理。

由分析可以看到,慢慢的為了適配多個機型,程序的啟動圖片也逐漸增多,為解決這個問題。iOS 8之后,可以使用xib來搭建啟動界面,這樣就可以同一個啟動界面,適配多個機型,減少啟動圖片占用的空間。

建議
  1. 以后的應用程序,都使用AutoLayout, 不要再用絕對定位。

  2. 使用類似網頁的方式來設計界面。設計師好,程序員也好,盡量使用點這個單位進行思考,而不要使用像素。比如,你需要做44 x 66個點的按鈕,2x模式,就乘以2, 3x模式就乘以3。這樣的思考方式可以大致估計到真實的物理長度。44個點,就是手機上導航欄,工具欄的高度。假如用像素思考,容易使得做出的圖片過大或者過小。

  3. 非矢量素材,就可以做尺寸最大的,之后再進行縮小。比如你需要兼容3x的屏幕,就直接做最高那種圖片。

  4. 而當使用Flash之類的矢量工具來做素材的時候,應該直接做點那個尺寸。比如44 x 66個點的按鈕。就建立一個44 x 66的場景。之后再導出成2倍圖,3倍圖,因為矢量放大不失真。不要建立一個3x的場景,導出成大圖片,再進行縮小,這樣就容易失真。更理想的是直接使用矢量圖。

  5. 假如是那種導航欄,工具欄之類的背景圖,需要橫跨整個屏幕??梢灾磺幸恍K,讓程序拉伸,拉伸方式是保持兩邊的像素不動,只拉伸最中間的一列像素。需要拉伸的話,橫方向就不要出現一些漸變色。

  6. 按鈕的點擊區域,不應該少于44個點,就算按鈕的圖片看起來比較小,也應該使得點按鈕周圍的透明區也有反應。

  7. 可以按照你當前最方便測試機子的型號來做一些主要預覽圖,效果圖。比如你手頭有iPhone 5,可以按照iPhone 5的尺寸,320 x 568個點,需要兼容iPhone 6 Plus,就使用3x的模式。這樣方便將圖片放進手機里面看實際的效果。有多個測試機,就選較大的,之后再進行一些細調。假如支持iPhone 6 Plus的橫屏模式,需要另外處理。

  8. 上面說的是應用的處理方式,游戲會有些特殊。現在很多游戲,按照1136 x 768的像素尺寸來設計場景,這樣可以同時兼容iPad和iPhone,并只使用一份圖。iPad 1x模式下尺寸是1024 x 768像素,iPhone 5在2x模式下,是1136 * 640像素。這種尺寸,可以將場景居中顯示,各自將場景拉伸到最大。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,572評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,071評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 175,409評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,569評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,360評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,895評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,979評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,123評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,643評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,559評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,742評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,250評論 5 356
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,981評論 3 346
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,363評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,622評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,354評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,707評論 2 370

推薦閱讀更多精彩內容