1.iPhone尺寸規格
設備
蘋果手機寬
寬度高
高度對角線
對角線邏輯分辨率(點)
比例因子
設備分辨率(像素)
PPI
3GS
2.4英寸(62.1毫米)
4.5英寸(115.5毫米)
3.5英寸
小320x480
@ 1X
小320x480
163
4(S)
2.31英寸(58.6毫米)
4.5英寸(115.2毫米)
3.5英寸
小320x480
@ 2倍
640×960
326
5C
2.33英寸(59.2毫米)
4.90英寸(124.4毫米)
4英寸
320x568
@ 2倍
640x1136
326
5(S)
2.31英寸(58.6毫米)
4.87英寸(123.8毫米)
4英寸
320x568
@ 2倍
640x1136
326
6
2.64英寸(67.0毫米)
5.44英寸(138.1毫米)
4.7英寸
375x667
@ 2倍
750x1334
326
6+
3.06英寸(77.8毫米)
6.22英寸(158.1毫米)
5.5英寸
414x736
@ 3倍
(1242x2208- >)
1080×1920401
1英寸= 2.54cm = 25.4mm
上表中的寬高(寬度/高度)為手機的物理尺寸,包括顯示屏和邊框。
以下為的iPhone4s的寬高示意圖:
我們通常所說的iPhone5的屏幕尺寸為4英寸,iPhone6屏幕尺寸為4.7英寸,指的是顯示屏對角線的長度(對角線)。
以下為iPhone5的?6 +的屏幕尺寸規格示意圖:
PPI(對角線像素每英寸):表示沿著對角線,每英寸所擁有的像素(Pixel)數目。
PPI數值越高,代表顯示屏能夠以越高的密度顯示圖像,即通常所說的分辨率越高,顆粒感越弱。
根據勾股定理,可以得知iPhone4的(一個或多個)的PPI計算公式為:
計算結果稍有出入,這是因為像素的離散采樣有鋸齒效應。
早期的iPhone3GS的屏幕分辨率是320 * 480(PPI = 163),iOS繪制圖形(CGPoint / CGSize / CGRect)均以點為單位(以點為單位):
1點= 1像素(每英寸點數=每英寸像素= PPI)
后來在iPhone4中,同樣大小(3.5英寸)的屏幕采用了Retina顯示技術,橫向,縱向方向像素密度都被放大到2倍,像素分辨率提高到(320x2)x(480x2)= 960x640(PPI = 326 ),顯像分辨率提升至iPhone3GS的4倍(1個點被渲染成1個2x2的像素矩陣)。
但是對于開發者來說,iOS的繪制圖形的API依然沿襲點(PT,注意區分印刷行業的“磅”)為單位在同樣的邏輯坐標系下(480):
1點= scale *像素(在iPhone4?6中,縮放因子scale = 2;在iPhone6 +中,縮放因子scale = 3)。
可以理解為:
scale =絕對長度比(point / pixel)=單位長度內的數量比(像素/點)
UIScreen.h中定義了該屬性:
//與屏幕相關的自然比例因子(只讀)
@property(nonatomic,readonly)CGFloatscaleNS_AVAILABLE_IOS(4_0);
-------------------------------------------------- ------------------------------
該值反映了將默認邏輯坐標空間轉換為該屏幕的設備坐標空間所需的比例因子。
使用點測量默認邏輯坐標空間。對于標準分辨率顯示,比例因子為1.0,一點等于一個像素。對于Retina顯示,比例因子為2.0,一個點由四個像素表示。
-------------------------------------------------- ------------------------------
為了自動適應分辨率,系統會根據設備實際分辨率,自動給UIScreen.scale賦值,該屬性對開發者只讀。
iOS8上新增了nativeScale屬性:
//物理屏幕的本機比例因子
@property(非原子,只讀)CGFloatnativeScaleNS_AVAILABLE_IOS(8_0);
以下是iPhone6 +下的輸出,初步看來nativeScale與規模沒有太大區別:
-------------------------------------------------- ------------------------------
(lldb)p(CGFloat)[[UIScreen mainScreen] scale]
(CGFloat)$ 1 = 3
(lldb)p(CGFloat)[[UIScreen mainScreen] nativeScale]
(CGFloat)$ 2 = 3
-------------------------------------------------- ------------------------------
在同樣的邏輯分辨率下,可以通過尺度參數識別是iPhone3GS的還是iPhone4的(S)以下基于nativeScale參數,定義了探測機型是否為iPhone6 +的宏:
-------------------------------------------------- ------------------------------
//不是UIUserInterfaceIdiomPad
#defineIS_IPHONE(UI_USER_INTERFACE_IDIOM()==UIUserInterfaceIdiomPhone)
//根據其本機比例檢測iPhone6 Plus
#defineIS_IPHONE_6PLUS(IS_IPHONE && [[UIScreenmainScreen] nativeScale] == 3.0f)
-------------------------------------------------- ------------------------------
那么,同樣的分辨率和比例,如何區分機型iPhone4與4s,iPhone5與5s呢?通過[[UIDevice currentDevice] model]只能判別iPhone,iPad,iPod大類,要判斷iPhone具體機型型號,則需要通過sysctlbyname( “hw.machine”)獲取詳細的設備參數信息予以甄別。
@ 2x意味著我們在迄今為止使用視網膜顯示器的所有iOS設備上看到的相同的“雙”視網膜分辨率,其中用戶界面中的每個虛擬點由每個維度(水平和垂直)中的兩個物理像素表示。
iPhone3GS時代,我們為一個應用提供圖標(或按鈕提供貼圖),只需要icon.png。針對現在的iPhone4?6 Retina顯示屏,需要制作額外的@ 2x高分辨率版本。
例如在iPhone3GS中,scale = 1,用的圖標是50x50pixel(logicalimage.size = 50x50point);在iPhone4?6中,scale = 2,則需要100×100像素(logical image.size = 50x50point,乘以image.scale =像素尺寸),并命名為icon@2x.png。
如果APP要同時兼容iPhone 3GS的?iPhone6,則需要提供icon.png/icon@2x.png兩種分辨率的圖片。
@ 3x表示新的“三重”視網膜分辨率,其中每個用戶接口點由三個顯示像素表示。單個@ 2x點是2×2平方的4像素;一個@ 3x點是一個3×3平方的9像素。“
iPhone6 +在實際渲染時,downsampling / 1.15(1242x2208- >1080x1920),準確的講,應該是@ 2.46x。蘋果為方便開發者用的是@ 3x的素材,然后再縮放到@ 2.46x上。
參考:“為什么iPhone 6 Plus要將3x渲染的2208x1242分辨率縮小到1080p屏幕上?”“詳解iPhone 6 Plus的奇點分辨率”“iPhone 6 Plus屏幕分辨率”
如果APP要同時兼容的iPhone3GS?iPhone6 +,則需要提供的icon.png /圖標@ 2x.png /圖標@ 3x.png三種分辨率的圖片。
需要注意的是,iOS APP圖標的尺寸和命名都需要遵守相關規范。
對于iPhone3,4 / 5 / 6,6 +三類機型,需要按分辨率提供相應的高倍圖并且文件名添加相應后綴,否則會拉伸(拉伸的/可調整大小)失真(模糊或邊角出現鋸齒) 。
以下基于的UIImage的兩類初始化API簡介高倍圖的適配:
<1> +imageNamed:方法該系統-使用緩存。,適合表視圖重復加載圖像的情形同時該API根據UIScreen的規模,自動查找所有游戲對應高倍圖后綴名(@ 2×)的文件,如果沒找到設置默認image.scale = 1.0。因此,使用該方法,無需特意指定高倍圖后綴。在實際運行時,系統如果發現當前設備是視網膜屏(標度= 2),會自動尋找“*@2x.png”命名格式的圖片,加載針對Retina屏的圖片素材,否則會失真。
<2> +imageWithContentsOfFile/ +imageWithData:(scale:)/ -initWithContentsOfFile:/ -initWithData:(規模:)
。這組方法創建的UIImage的對象沒有使用系統緩存,并且指定文件名必須包含明確的高倍圖后綴如果文件包含@ 2X后綴,則image.scale = 2.0;否則默認image.scale = 1.0,同樣對于視網膜屏將會失真
<3>
//整個屏幕的邊界(本地坐標系,起點為[0,0])
@property(nonatomic,readonly)CGRectbounds;
-------------------------------------------------- ------------------------------
//考慮轉屏的影響,按照實際屏幕方向(UIDeviceOrientation)的寬高
#defineSCREEN_WIDTH([UIScreenmainScreen] .bounds.size.width)
#defineSCREEN_HEIGHT([UIScreenmainScreen] .bounds.size.height)
#defineSTATUSBAR_HEIGHT([UIApplicationsharedApplication] .statusBarFrame.size.height)
//不考慮轉屏的影響,只取豎屏(UIDeviceOrientationPortrait)的寬高
#defineSCREEN_WIDTHMIN([UIScreenmainScreen] .bounds.size.width,[UIScreenmainScreen] .bounds.size.height)
#defineSCREEN_HEIGHTMAX([UIScreenmainScreen] .bounds.size.height,[UIScreenmainScreen] .bounds.size.width)
#defineSTATUSBAR_HEIGHTMIN([UIApplicationsharedApplication] .statusBarFrame.size.width,[UIApplicationsharedApplication] .statusBarFrame.size.height)
-------------------------------------------------- ------------------------------
iOS8上新增了nativeBounds屬性,輸出豎屏像素級分辨率:
//物理屏幕的邊界矩形,以像素為單位。(只讀)
//此矩形基于縱向朝向的設備。該值不隨設備旋轉而改變。
@property(nonatomic,readonly)CGRectnativeBoundsNS_AVAILABLE_IOS(8_0);
以下是iPhone6 +下的輸出:
-------------------------------------------------- ------------------------------
(LLDB)poNSStringFromCGRect([(UIScreen *)[UIScreen mainScreen]界限
]){{0,0},{414,736}}
(LLDB)poNSStringFromCGRect([(UIScreen *)[UIScreen mainScreen]
nativeBounds]){{0 ,0},{1242,2208}}
-------------------------------------------------- ------------------------------
//應用程序屏幕區域的點數(如果可見,則顯示屏幕減去狀態欄)
// bounds除去系統狀態欄
@property(nonatomic,readonly)CGRectapplicationFrame;
-------------------------------------------------- ------------------------------
// APPFRAME_WIDTH = SCREEN_WIDTH
#defineAPPFRAME_WIDTH([UIScreen mainScreen] .applicationFrame.size.width)
// APPFRAME_HEIGHT = SCREEN_HEIGHT-STATUSBAR_HEIGHT
//注意:橫屏(UIDeviceOrientationLandscape)時,iOS8上默認隱藏狀態欄,此時APPFRAME_HEIGHT = SCREEN_HEIGHT
#defineAPPFRAME_HEIGHT([UIScreen mainScreen] .applicationFrame.size.height)
-------------------------------------------------- ------------------------------
下圖展示了邊界和幀的區別:
從的iPhone3GS / iPhone4的(一個或多個)過渡到iPhone5的(一個或多個)時,在邏輯上寬度不變高度稍高,之前舊的素材和布局通過AutoresizingFlexible簡單適配即可運行得很好,但由于高寬比增大,上下兩端出現黑粗邊(典型如LaunchImage)從分辨率的角度來看,除了需要提供LaunchImage這種滿屏圖,其他基本沿用二倍圖(@ 2×);從屏幕尺寸角度來看,需要對縱向排版略加調整。
從iPhone5的(一個或多個)發展到iPhone6(+),由于高寬比保持不變,iOS的對圖標,圖片,字體進行等比放大自適應,清晰度會有所降低。同時,絕對坐標布局會導致在大屏下出現偏左偏上的問題從分辨率的角度來看,iPhone6沿用二倍圖(@ 2×),但需為iPhone6 +提供更高的三倍圖(@ 3×);從屏幕尺寸角度來看,需要重新對UI元素尺寸和布局進行適配,以期視覺協調。
我們先來看一下的iPhone4?6(+)的屏幕高寬比:
iPhone4的(一個或多個):分辨率960 * 640,高寬比1.5
的iPhone5(S):分辨率1136 * 640,高寬比1.775
iPhone6:分辨率1334 * 750,高寬比1.779
iPhone6 +:分辨率1920×1080,高寬比1.778
可粗略認為iPhone5(s),6(+)的高寬比是一致的(16:9),即可以等比縮放因此可以按寬度
適配:fitScreenWidth = width *(SCREEN_WIDTH / 320 )
這樣,共有的iPhone3 / 4 / 5,6,6- +三組寬度,在iPhone6,6 +下將按比例橫向放大。
在同樣的寬度下,iPhone4(s)的屏高比iPhone5(s)低,若縱向排版緊張,可以iPhone5(s)為基準,按高度
適配:fitScreenHeight = height *(SCREEN_HEIGHT / 568)
共有iPhone3 / 4,5,6,6+四組高度,在iPhone3的/ 4下將按比例縱向縮小,在iPhone6,6 +下將按比例縱向放大。
這里需要注意iPhone / iOS雙環上網的熱點欄對縱向布局的影響:iPhone作為個人熱點且有連接時,系統狀態欄下面會多一行熱點連接提示欄“個人熱點:*連接”,縱向會下壓20pt ,[UIApplication sharedApplication] .statusBarFrame高度變為40pt;當所有連接都斷開時,熱點欄消失,縱向高度恢復正常為20pt。詳情可參考“iPhone / iOS開啟個人熱點的縱向適配小結”。
另外,iPhone的【設置】【通用】【輔助功能】中可以設置調節【更大字體】,APP可以也。按字號適配:
例如適配表視圖(UITableView的:UIScrollView的),無法左右滑動,因此無論字號縮放比例多大,橫向都不應超過SCREEN_WIDTH。注意限定控件元素內容區域寬度以及間距,并設置適當的LineBreakMode。表視圖支持上下滑動,因此縱向上的表格行高和內容區域高度可按字號縮放。
對于縱向也不支持滑動的視圖,在屏幕可見視區內排版時,最好不要隨字號縮放,否則可能超出既定寬高。
考慮到iPhone機型的多樣性,不可能針對iPhone4的(S),5(S),6,6- +四種屏幕尺寸出四套視覺交互稿,也不要基于某一機型從上往下,從往右左給絕對標注,而應該關注子視圖在上海華盈中的相對位置(EdgeInsets /幀/中心)以及siblingView之間的偏移(膠印),盡量給出適合自動布局的相對布局比例(理想情況是只給百分比)。假如交互按照iPhone5的(一個或多個)下絕對標注,則在iPhone4的(一個或多個)上可能擠出屏幕底部,而在iPhone6(+)上則可能橫向偏左或縱向偏上。
開發人員基于與屏幕邊緣的間距(保證金/ EdgeInsets),定位邊緣處的控件(釘釘子)作為參照,基于然后控件尺寸狀語從句:間隙進行相對計算排版。這樣,若釘子移動,相鄰控件將順向偏移,不會因為局部調整而出現凌亂。
蘋果在WWDC2012 iOS6中就已提出了Auto Layout的概念,即使用約束條件來定義視圖的位置和尺寸,以適應不同尺寸和分辨率的屏幕。
最后,除了對屏幕尺寸和分辨率進行適配之外,還需對iOS SDK中相關的DEPRECATED API進行適配。典型的如:
(1)UILineBreakMode-> NSLineBreakMode
(2)UITextAlignment-> NSTextAlignment
(3)sizeWithFont: - > boundingRectWithSize:
(4)stretchableImageWithLeftCapWidth:topCapHeight: - > resizableImageWithCapInsets:
(5)...
參考:
iOS8中的UIScreen”“檢測iPhone 6/6 +屏幕尺寸的點值”
”在Xcode 6中用矢量化PDF(矢量化PDF)來支持各種尺寸的iPhone“”iOS8適配須知“”適配iOS8備忘錄“”iOS界面適配(一)二)(三)“”iPhone6/6 +適配心得“”iOS8 / Xcode6 / iPhone6(+)適配“”APP適配iOS8,iPhone6(+)截圖簡要說明“”按比例快速兼容適配iPhone6 / 6 Plus“”iOS的APP如何適應iPhone5S / 6/6 +三種屏幕的尺寸? “