1:iPhone尺寸規(guī)格
2:屏幕尺寸
我們通常所說(shuō)的iPhone5屏幕尺寸為4英寸揽思、iPhone6屏幕尺寸為4.7英寸,指的是顯示屏對(duì)角線(xiàn)的長(zhǎng)度(diagonal)
3:像素密度PPI
PPI(Pixel Per Inch by diagonal):表示沿著對(duì)角線(xiàn),每英寸所擁有的像素(Pixel)數(shù)目场躯。
PPI數(shù)值越高,代表顯示屏能夠以越高的密度顯示圖像,即通常所說(shuō)的分辨率越高、顆粒感越弱。
根據(jù)勾股定理
計(jì)算結(jié)果稍有出入,這是因?yàn)橄袼氐碾x散采樣有鋸齒效應(yīng)。
4:縮放因子(scale factorbetween logic point and device pixel)
(1)Scale起源
早期的iPhone3GS的屏幕分辨率是320*480(PPI=163),iOS繪制圖形(CGPoint/CGSize/CGRect)均以point為單位(measured in points):
1 point = 1 pixel(Point Per Inch=Pixel Per Inch=PPI)
后來(lái)在iPhone4中,同樣大小(3.5 inch)的屏幕采用了Retina顯示技術(shù),橫、縱向方向像素密度都被放大到2倍,像素分辨率提高到(320x2)x(480x2)= 960x640(PPI=326), 顯像分辨率提升至iPhone3GS的4倍(1個(gè)Point被渲染成1個(gè)2x2的像素矩陣)蠢挡。
但是對(duì)于開(kāi)發(fā)者來(lái)說(shuō),iOS繪制圖形的API依然沿襲point(pt,注意區(qū)分印刷行業(yè)的“磅”)為單位。
在同樣的邏輯坐標(biāo)系下(320x480):
1 point = scale*pixel
(在iPhone4~6中,縮放因子scale=2;在iPhone6+中,縮放因子scale=3)凳忙。
結(jié)論:
scale=絕對(duì)長(zhǎng)度比(point/pixel)=單位長(zhǎng)度內(nèi)的數(shù)量比(pixel/point)
(2)UIScreen.scale
UIScreen.h
@property(nonatomic,readonly)CGFloatscaleNS_AVAILABLE_IOS(4_0);
為了自動(dòng)適應(yīng)分辨率,系統(tǒng)會(huì)根據(jù)設(shè)備實(shí)際分辨率,自動(dòng)給UIScreen.scale賦值,該屬性對(duì)開(kāi)發(fā)者只讀袒哥。
(3)UIScreen.nativeScale(iOS8新增了nativeScale屬性:nativeScale與scale沒(méi)有太大區(qū)別)
@property(nonatomic,readonly)CGFloatnativeScaleNS_AVAILABLE_IOS(8_0);
(4)機(jī)型判別
在同樣的邏輯分辨率下,可以通過(guò)scale參數(shù)識(shí)別是iPhone3GS還是iPhone4(s)。以下基于nativeScale參數(shù),定義了探測(cè)機(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呢?通過(guò)[[UIDevice currentDevice] model]只能判別iPhone堡称、iPad、iPod大類(lèi),要判斷iPhone具體機(jī)型型號(hào),則需要通過(guò)sysctlbyname("hw.machine")獲取詳細(xì)的設(shè)備參數(shù)信息予以甄別艺演。
5:@2x @3x及高倍圖適配
(1)@2x
iPhone3GS時(shí)代,我們?yōu)橐粋€(gè)應(yīng)用提供圖標(biāo)(或按鈕提供貼圖),只需要icon.png却紧。針對(duì)現(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兩種分辨率的圖片晓殊。
(2)@3x
Phone6+在實(shí)際渲染時(shí),downsampling/1.15(1242x2208->1080x1920),準(zhǔn)確的講,應(yīng)該是@2.46x。蘋(píng)果為方便開(kāi)發(fā)者用的是@3x的素材,然后再縮放到@2.46x上伤提。
如果APP要同時(shí)兼容iPhone3GS~iPhone6+,則需要提供icon.png/icon@2x.png/icon@3x.png三種分辨率的圖片巫俺。需要注意的是,iOS APP圖標(biāo)的尺寸和命名都需要遵守相關(guān)規(guī)范。
參考:一張圖幫你看懂 iPhone 6 Plus 屏幕分辨率
(3)加載圖片的方式
<1>
+imageNamed:
該方法使用系統(tǒng)緩存,適合表視圖重復(fù)加載圖像的情形肿男。同時(shí)該API根據(jù)UIScreen的scale,自動(dòng)查找包含對(duì)應(yīng)高倍圖后綴名(@2x)的文件,如果找到二倍圖,則image.scale=2.0,對(duì)應(yīng)邏輯size大小以point度量(pixel度量的一半);如果沒(méi)找到設(shè)置默認(rèn)image.scale=1.0,對(duì)應(yīng)邏輯size大小同像素尺寸介汹。因此,
使用該方法,無(wú)需特意指定高倍圖后綴。在實(shí)際運(yùn)行時(shí),系統(tǒng)如果發(fā)現(xiàn)當(dāng)前設(shè)備是Retina屏(scale=2),會(huì)自動(dòng)尋找"*@2x.png"命名格式的圖片,加載針對(duì)Retina屏的圖片素材,否則會(huì)失真舶沛。
<2>
+imageWithContentsOfFile
+imageWithData:(scale:)
-initWithContentsOfFile:
-initWithData:(scale:)
這組方法創(chuàng)建的UIImage對(duì)象沒(méi)有使用系統(tǒng)緩存,并且指定文件名必須包含明確的高倍圖后綴嘹承。
如果文件名包含@2x后綴,則image.scale=2.0;否則默認(rèn)image.scale=1.0,同樣對(duì)于Retina屏將會(huì)失真。
<3>
目前,適配iPhone6+時(shí),除了一些鋪滿(mǎn)全屏的大圖(LogoIcon如庭、LaunchImage)需提供三倍圖,其他的小圖仍可沿用原有的二倍圖自適應(yīng)拉伸叹卷。
6:Screen Bounds ?& ?Application Frame
(1) UIScreen.bounds
// Bounds of entire screen in points(本地坐標(biāo)系,起點(diǎn)為[0,0])
@property(nonatomic,readonly)CGRectbounds;
//考慮?轉(zhuǎn)屏?的影響,按照實(shí)際屏幕方向(UIDevice ?Orientation)的寬高
#defineSCREEN_WIDTH([UIScreenmainScreen].bounds.size.width)
#defineSCREEN_HEIGHT([UIScreenmainScreen].bounds.size.height)
#defineSTATUSBAR_HEIGHT([UIApplicationsharedApplication].statusBarFrame.size.height)
//不考慮轉(zhuǎn)屏的影響,只取豎屏(UIDevice OrientationPortrait)的寬高
#defineSCREEN_WIDTH? MIN([UIScreen mainScreen].bounds.size.width, [UIScreenmainScreen].bounds.size.height)
#defineSCREEN_HEIGHT? MAX([UIScreen mainScreen].bounds.size.height? ? ? [UIScreenmainScreen].bounds.size.width)
#defineSTATUSBAR_HEIGHT MIN([UIApplicationsharedApplication].statusBarFrame.size.width,
[UIApplicationsharedApplication].statusBarFrame.size.height)
7:機(jī)型尺寸適配(Screen Scale Adaption)
待續(xù)