原帖地址:http://blog.csdn.net/phunxm/article/details/42174937/
僅供我個(gè)人收藏學(xué)習(xí)耀里,原博主如不同意請聯(lián)系qq651263878進(jìn)行刪除,在此表示感謝以及歉意。
1.iPhone尺寸規(guī)格
后續(xù)上市的iPhone7以及iPhone7plus ?與六代相同
1 inch = 2.54cm = 25.4mm
上表中的寬高(width/height)為手機(jī)的物理尺寸,包括顯示屏和邊框五垮。
以下為iPhone4s的寬高示意圖:
我們通常所說的iPhone5屏幕尺寸為4英寸辛润、iPhone6屏幕尺寸為4.7英寸,指的是顯示屏對角線的長度(diagonal)健爬。
以下為iPhone5~6+的屏幕尺寸規(guī)格示意圖:
PPI(Pixel Per Inch by diagonal):表示沿著對角線,每英寸所擁有的像素(Pixel)數(shù)目么介。
PPI數(shù)值越高娜遵,代表顯示屏能夠以越高的密度顯示圖像,即通常所說的分辨率越高壤短、顆粒感越弱设拟。
根據(jù)勾股定理,可以得知iPhone4(s)的PPI計(jì)算公式為:
計(jì)算結(jié)果稍有出入鸽扁,這是因?yàn)橄袼氐碾x散采樣有鋸齒效應(yīng)蒜绽。
6.縮放因子(scale factorbetween logic point and device pixel)
早期的iPhone3GS的屏幕分辨率是320*480(PPI=163),iOS繪制圖形(CGPoint/CGSize/CGRect)均以point為單位(measured in points):
1 point = 1 pixel(Point Per Inch=Pixel Per Inch=PPI)
后來在iPhone4中桶现,同樣大卸阊拧(3.5 inch)的屏幕采用了Retina顯示技術(shù),橫骡和、縱向方向像素密度都被放大到2倍相赁,像素分辨率提高到(320x2)x(480x2)= 960x640(PPI=326),?顯像分辨率提升至iPhone3GS的4倍(1個(gè)Point被渲染成1個(gè)2x2的像素矩陣)慰于。
但是對于開發(fā)者來說钮科,ios繪制圖形的API依然沿襲point(pt,注意區(qū)分印刷行業(yè)的“磅”)為單位婆赠。在同樣的邏輯坐標(biāo)系下(320x480):
1 point = scale*pixel(在iPhone4~6中绵脯,縮放因子scale=2;在iPhone6+中休里,縮放因子scale=3)蛆挫。
可以理解為:
scale=絕對長度比(point/pixel)=單位長度內(nèi)的數(shù)量比(pixel/point)
UIScreen.h中定義了該屬性:
// The natural scale factor associated with the screen.(read-only)
@property(nonatomic,readonly)CGFloatscaleNS_AVAILABLE_IOS(4_0);
--------------------------------------------------------------------------------
This value reflects the scale factor needed to convert from the defaultlogical coordinate spaceinto thedevice coordinate spaceof this screen.
The default logical coordinate space is measured usingpoints. Forstandard-resolutiondisplays, the scale factor is 1.0 andone point equals one pixel. ForRetinadisplays, the scale factor is 2.0 andone point is represented by four pixels.
--------------------------------------------------------------------------------
為了自動適應(yīng)分辨率,系統(tǒng)會根據(jù)設(shè)備實(shí)際分辨率妙黍,自動給UIScreen.scale賦值悴侵,該屬性對開發(fā)者只讀。
iOS8新增了nativeScale屬性:
// Native scale factor of the physical screen
@property(nonatomic,readonly)CGFloatnativeScaleNS_AVAILABLE_IOS(8_0);
以下是iPhone6+下的輸出拭嫁,初步看來nativeScale與scale沒有太大區(qū)別:
--------------------------------------------------------------------------------
(lldb)p (CGFloat)[[UIScreen mainScreen] scale]
(CGFloat) $1 = 3
(lldb) p(CGFloat)[[UIScreen mainScreen] nativeScale]
(CGFloat) $2 = 3
--------------------------------------------------------------------------------
在同樣的邏輯分辨率下可免,可以通過scale參數(shù)識別是iPhone3GS還是iPhone4(s)抓于。以下基于nativeScale參數(shù),定義了探測機(jī)型是否為iPhone6+的宏:
--------------------------------------------------------------------------------
// not UIUserInterfaceIdiomPad
#defineIS_IPHONE(UI_USER_INTERFACE_IDIOM() ==UIUserInterfaceIdiomPhone)
// detect iPhone6 Plus based on its native scale
#defineIS_IPHONE_6PLUS(IS_IPHONE && [[UIScreenmainScreen] nativeScale] == 3.0f)
--------------------------------------------------------------------------------
那么浇借,同樣的分辨率和scale捉撮,如何區(qū)分機(jī)型iPhone4與4s、iPhone5與5s呢逮刨?通過[[UIDevice currentDevice] model]只能判別iPhone呕缭、iPad堵泽、iPod大類修己,要判斷iPhone具體機(jī)型型號,則需要通過sysctlbyname("hw.machine")獲取詳細(xì)的設(shè)備參數(shù)信息予以甄別迎罗。
@2xmeans the same “double”retina resolution that we’veseen on all iOS devices with retina displays to date, where each virtual pointin the user interface is represented bytwophysical pixels on thedisplayin each dimension, horizontal and vertical.
iPhone3GS時(shí)代睬愤,我們?yōu)橐粋€(gè)應(yīng)用提供圖標(biāo)(或按鈕提供貼圖),只需要icon.png纹安。針對現(xiàn)在的iPhone4~6 Retina顯示屏尤辱,需要制作額外的@2x高分辨率版本。
例如在iPhone3GS中厢岂,scale=1光督,用的圖標(biāo)是50x50pixel(logicalimage.size=50x50point);在iPhone4~6中塔粒,scale=2结借,則需要100×100pixel(logical image.size=50x50point,乘以image.scale=dimensions in pixels)卒茬,并且命名為icon@2x.png船老。
如果APP要同時(shí)兼容iPhone3GS~iPhone6,則需要提供icon.png/icon@2x.png兩種分辨率的圖片圃酵。
@3xmeans a new “triple” retina resolution, where eachuser interface point is represented bythreedisplay pixels. A single @2x pointis a 2?×?2 square of 4 pixels; an @3x point is a 3?×?3 square of 9 pixels.”
iPhone6+在實(shí)際渲染時(shí)柳畔,downsampling/1.15(1242x2208->1080x1920),準(zhǔn)確的講郭赐,應(yīng)該是@2.46x薪韩。蘋果為方便開發(fā)者用的是@3x的素材,然后再縮放到@2.46x上捌锭。
參考:《為什么iPhone 6 Plus要將3x渲染的2208x1242分辨率縮小到1080p屏幕上俘陷?》《詳解iPhone 6 Plus的奇葩分辨率》《iPhone 6 Plus屏幕分辨率》
如果APP要同時(shí)兼容iPhone3GS~iPhone6+,則需要提供icon.png/icon@2x.png/icon@3x.png三種分辨率的圖片舀锨。
需要注意的是岭洲,iOS APP圖標(biāo)的尺寸和命名都需要遵守相關(guān)規(guī)范。
對于iPhone3坎匿、4/5/6盾剩、6+三類機(jī)型雷激,需要按分辨率提供相應(yīng)的高倍圖并且文件名添加相應(yīng)后綴,否則會拉伸(stretchable/resizable)失真(模糊或邊角出現(xiàn)鋸齒)告私。
以下基于UIImage的兩類初始化API簡介高倍圖的適配:
<1>+imageNamed:該方法使用系統(tǒng)緩存屎暇,適合表視圖重復(fù)加載圖像的情形。同時(shí)該API根據(jù)UIScreen的scale驻粟,自動查找包含對應(yīng)高倍圖后綴名(@2x)的文件根悼,如果找到二倍圖,則image.scale=2.0蜀撑,對應(yīng)邏輯size大小以point度量(pixel度量的一半)挤巡;如果沒找到設(shè)置默認(rèn)image.scale=1.0,對應(yīng)邏輯size大小同像素尺寸酷麦。因此矿卑,使用該方法,無需特意指定高倍圖后綴沃饶。在實(shí)際運(yùn)行時(shí)母廷,系統(tǒng)如果發(fā)現(xiàn)當(dāng)前設(shè)備是Retina屏(scale=2),會自動尋找"*@2x.png"命名格式的圖片糊肤,加載針對Retina屏的圖片素材琴昆,否則會失真。
<2>+imageWithContentsOfFile/+imageWithData:(scale:)/-initWithContentsOfFile:/-initWithData:(scale:)
這組方法創(chuàng)建的UIImage對象沒有使用系統(tǒng)緩存馆揉,并且指定文件名必須包含明確的高倍圖后綴业舍。如果文件名包含@2x后綴,則image.scale=2.0把介;否則默認(rèn)image.scale=1.0勤讽,同樣對于Retina屏將會失真。
<3>目前拗踢,適配iPhone6+時(shí)脚牍,除了一些鋪滿全屏的大圖(LogoIcon、LaunchImage)需提供三倍圖巢墅,其他的小圖仍可沿用原有的二倍圖自適應(yīng)拉伸诸狭。
9.Screen Bounds&Application Frame
// Bounds of entire screen in points(本地坐標(biāo)系,起點(diǎn)為[0,0])
@property(nonatomic,readonly)CGRectbounds;
--------------------------------------------------------------------------------
//考慮轉(zhuǎn)屏的影響君纫,按照實(shí)際屏幕方向(UIDeviceOrientation)的寬高
#defineSCREEN_WIDTH([UIScreenmainScreen].bounds.size.width)
#defineSCREEN_HEIGHT([UIScreenmainScreen].bounds.size.height)
#defineSTATUSBAR_HEIGHT([UIApplicationsharedApplication].statusBarFrame.size.height)
//不考慮轉(zhuǎn)屏的影響驯遇,只取豎屏(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屬性,輸出豎屏像素級分辨率:
// The bounding rectangle of the physical screen,measured inpixels. (read-only)
// This rectangle is based on the device in a portrait-up orientation.?This value does not change as the device rotates.
@property(nonatomic,readonly)CGRectnativeBoundsNS_AVAILABLE_IOS(8_0);
以下是iPhone6+下的輸出:
--------------------------------------------------------------------------------
(lldb) poNSStringFromCGRect([(UIScreen*)[UIScreen mainScreen] bounds])
{{0, 0}, {414, 736}}
(lldb) poNSStringFromCGRect([(UIScreen*)[UIScreen mainScreen] nativeBounds])
{{0, 0}, {1242, 2208}}
--------------------------------------------------------------------------------
// Frame of application screen area in points (i.e.entire screenminusstatus bar if visible)
// bounds除去系統(tǒng)狀態(tài)欄
@property(nonatomic,readonly)CGRectapplicationFrame;
--------------------------------------------------------------------------------
// APPFRAME_WIDTH=SCREEN_WIDTH
#defineAPPFRAME_WIDTH([UIScreen mainScreen].applicationFrame.size.width)
// APPFRAME_HEIGHT=SCREEN_HEIGHT-STATUSBAR_HEIGHT
//注意:橫屏(UIDeviceOrientationLandscape)時(shí)蓄髓,iOS8默認(rèn)隱藏狀態(tài)欄叉庐,此時(shí)APPFRAME_HEIGHT=SCREEN_HEIGHT
#defineAPPFRAME_HEIGHT([UIScreen mainScreen].applicationFrame.size.height)
--------------------------------------------------------------------------------
下圖展示了bounds和frame的區(qū)別:
10.機(jī)型尺寸適配(Screen Scale Adaption)
從iPhone3GS/iPhone4(s)過渡到iPhone5(s)時(shí),在邏輯上寬度不變高度稍高会喝,之前舊的素材和布局通過AutoresizingFlexible簡單適配即可運(yùn)行得很好陡叠,但由于高寬比增大玩郊,上下兩端出現(xiàn)黑粗邊(典型如LaunchImage)。從分辨率的角度來看枉阵,除了需要提供LaunchImage這種滿屏圖译红,其他基本沿用二倍圖(@2x)兴溜;從屏幕尺寸角度來看侦厚,需要對縱向排版略加調(diào)整。
從iPhone5(s)發(fā)展到iPhone6(+)拙徽,由于高寬比保持不變刨沦,iOS對圖標(biāo)、圖片斋攀、字體進(jìn)行等比放大自適應(yīng)已卷,清晰度會有所降低。同時(shí)淳蔼,絕對坐標(biāo)布局會導(dǎo)致在大屏下出現(xiàn)偏左偏上的問題。從分辨率的角度來看裁眯,iPhone6沿用二倍圖(@2x)鹉梨,但需為iPhone6+提供更高的三倍圖(@3x);從屏幕尺寸角度來看穿稳,需要重新對UI元素尺寸和布局進(jìn)行適配存皂,以期視覺協(xié)調(diào)。
我們先來看一下iPhone4~6(+)的屏幕高寬比:
iPhone4(s):分辨率960*640逢艘,高寬比1.5
iPhone5(s):分辨率1136*640旦袋,高寬比1.775
iPhone6:分辨率1334*750,高寬比1.779
iPhone6+:分辨率1920*1080它改,高寬比1.778
可粗略認(rèn)為iPhone5(s)疤孕、6(+)的高寬比是一致的(16:9),即可以等比例縮放央拖。因此可以按寬度適配:
fitScreenWidth= width*(SCREEN_WIDTH/320)
這樣祭阀,共有iPhone3/4/5、6鲜戒、6+三組寬度专控,在iPhone6、6+下將按比例橫向放大遏餐。
在同樣的寬度下伦腐,iPhone4(s)的屏高比iPhone5(s)低失都,若縱向排版緊張,可以iPhone5(s)為基準(zhǔn)嘁扼,按高度適配:
fitScreenHeight= height*(SCREEN_HEIGHT/568)
共有iPhone3/4趁啸、5不傅、6访娶、6+四組高度崖疤,在iPhone3/4下將按比例縱向縮小劫哼,在iPhone6权烧、6+下將按比例縱向放大般码。
這里需要注意iPhone/iOS雙環(huán)上網(wǎng)的熱點(diǎn)欄對縱向布局的影響:iPhone作為個(gè)人熱點(diǎn)且有連接時(shí)板祝,系統(tǒng)狀態(tài)欄下面會多一行熱點(diǎn)連接提示欄"Personal Hotspot: * Connection"扔字,縱向會下壓20pt革为,[UIApplication sharedApplication].statusBarFrame高度變?yōu)?0pt;當(dāng)所有連接都斷開時(shí),熱點(diǎn)欄消失博其,縱向高度恢復(fù)正常為20pt慕淡。詳情可參考《iPhone/iOS開啟個(gè)人熱點(diǎn)的縱向適配小結(jié)》峰髓。
另外,iPhone的【設(shè)置】【通用】【輔助功能】中可以設(shè)置調(diào)節(jié)【更大字體】徐紧,APP也可以按字號適配:
例如適配表視圖(UITableView:UIScrollView)并级,無法左右滑動死遭,因此無論字號縮放比例多大,橫向都不應(yīng)超過SCREEN_WIDTH至非。注意限定控件元素內(nèi)容區(qū)域?qū)挾纫约伴g距荒椭,并設(shè)置適當(dāng)?shù)腖ineBreakMode趣惠。表視圖支持上下滑動味悄,因此縱向上的表格行高和內(nèi)容區(qū)域高度可按字號縮放侍瑟。
對于縱向也不支持滑動的視圖费韭,在屏幕可見視區(qū)內(nèi)排版時(shí)星持,最好不要隨字號縮放督暂,否則可能超出既定寬高。
考慮到iPhone機(jī)型的多樣性酒来,不可能針對iPhone4(s)辽社、5(s)滴铅、6汉匙、6+四種屏幕尺寸出四套視覺交互稿,也不要基于某一機(jī)型從上往下伤锚、從左往右給絕對標(biāo)注屯援,而應(yīng)該關(guān)注subView在superView中的相對位置(EdgeInsets/Frame/Center)以及siblingView之間的偏移(Offset)狞洋,盡量給出適合Autolayout的相對布局比例(理想情況是只給百分比)。假如交互按照iPhone5(s)下絕對標(biāo)注惕它,則在iPhone4(s)上可能擠出屏幕底部,而在iPhone6(+)上則可能橫向偏左或縱向偏上。
開發(fā)人員基于與屏幕邊緣的間距(Margin/EdgeInsets)兆蕉,定位邊緣處的控件(釘釘子)作為參照虎韵,然后基于控件尺寸和間隙進(jìn)行相對計(jì)算排版包蓝。這樣,若釘子移動届巩,相鄰控件將順向偏移腕唧,不會因?yàn)榫植空{(diào)整而出現(xiàn)凌亂瘾英。
我們截取 iPhone5s QQ 文件助手列表中的文件cell四苇,使用SketchMeasure對其進(jìn)行測量標(biāo)注。
打開[截圖.png]文件方咆,由于不包含 Sketch 圖元對象,無法進(jìn)行 measure 標(biāo)注(提示:請?jiān)诋嫲逯惺褂迷摴δ埽凹堋R虼税曷福谝徊叫枰獙σ鄬?biāo)注的各個(gè)UI元素進(jìn)行對象化。依次Insert Artboard 創(chuàng)建圖層?frame片拍、thumbnail煌集、title、detail、source乍赫、button诈皿。
選中整個(gè)cell的frame(bounds)措左,進(jìn)行 Measure size:width=640px(SCREEN_WIDTH),height=168px。默認(rèn)橫向尺寸和縱向參考線都居中導(dǎo)致標(biāo)注重疊荐吉,將縱向參考線右移至合適位置攻礼;也可選中WIDTH標(biāo)注圖層中的text和label元素深员,在不移動參考線的前提下叠赐,利用鼠標(biāo)局部移動標(biāo)注字面量文黎。
(1)縮略圖標(biāo)
在左側(cè)邊欄layer list中選中frame院究,再command選中文件類型縮略圖對象thumbnail位他,進(jìn)行 Measure spacing骗奖,丈量縮略圖左側(cè)相對frame的間距為24px。
選中文件類型縮略圖對象thumbnail,進(jìn)行 measure size亡问,由于正方形等寬為112px*112px,故橫縱標(biāo)注重疊無影響后添。thumbnail在frame中縱向整體居中馅精,因此上下邊距計(jì)算均攤即可茄蚯,無需再給定標(biāo)注。
(2)傳輸按鈕
對 button 和 frame 進(jìn)行 Measure spacing隐孽,丈量按鈕右側(cè)相對frame的間距為24px抗俄。
選中按鈕button進(jìn)行 measure size查剖,其寬高為144px*60px钾虐。橫縱標(biāo)注重疊影響視覺,將縱向參考線右移至合適位置笋庄。
button在frame中縱向整體居中效扫,因此上下邊距計(jì)算均攤即可,無需再給定標(biāo)注直砂。
(3)文件信息
對thumbnail和detail(title菌仁、source等寬且左對齊)進(jìn)行 Measure spacing,丈量圖標(biāo)右側(cè)相對detail的間距為20px静暂;對button和detail進(jìn)行 Measure spacing济丘,丈量按鈕左側(cè)相對detail間距為20px。這樣洽蛀,左側(cè)釘住thumbnail闪盔,右側(cè)釘住button弯院,中間信息部分的寬度無需給定,計(jì)算被動約束的橫向余量即可泪掀。具體編程時(shí),調(diào)用sizeWithFont/boundingRectWithSize 可動態(tài)計(jì)算每行 label 的自然寬度颂碘,一般title都會超過約束寬度异赫,因此需設(shè)置 lineBreakMode指定Wrapping省略或Truncating截?cái)喔袷健?/p>
選中文件信息第1行標(biāo)題title和第2行詳情detail,進(jìn)行 Measure spacing头岔,測量縱向相對間距10px塔拳;第2行詳情detail和第3行來源的縱向相對間距也為10px。一般 UILabel 的文本在給定字體下的縱向自然顯示無約束峡竣,調(diào)用sizeWithFont/boundingRectWithSize 可動態(tài)計(jì)算每行 label 的自然高度靠抑,title的上間距和source的底間距無需給定,通過計(jì)算縱向余量均攤即可适掰。
可簡單的基于屏寬橫縱比例進(jìn)行scale縮放颂碧,將以上測量出的標(biāo)注應(yīng)用到iPhone6(+)大屏下,當(dāng)然交互設(shè)計(jì)工程師最好還是針對特定機(jī)型都給定適配標(biāo)注类浪。蘋果在WWDC2012 iOS6中已提出了Auto Layout的概念载城,即使用約束條件來定義視圖的位置和尺寸,以適應(yīng)不同尺寸和分辨率的屏幕费就。
最后诉瓦,除了對屏幕尺寸和分辨率進(jìn)行適配之外,還需對iOS SDK中相關(guān)的DEPRECATED API進(jìn)行適配力细。典型的如:
(1)UILineBreakMode->NSLineBreakMode
(2)UITextAlignment->NSTextAlignment
(3)sizeWithFont:->boundingRectWithSize:
(4)stretchableImageWithLeftCapWidth:topCapHeight:->resizableImageWithCapInsets:
(5)...
參考:
《iOS設(shè)備的屏幕尺寸睬澡、分辨率及其屏幕邊長比例》
《Detecting iPhone 6/6+ screen sizes in point values》
《在Xcode 6中用矢量化PDF(vectorized PDF)來支持各種尺寸的iPhone》
《iOS8適配須知》