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 +三种屏幕的尺寸? “