UI适配iOSiOS学习

iOS开发:iPhone尺寸和适配

2017-01-16  本文已影响10255人  iOS_SXH

1:iPhone尺寸规格

尺寸表格:1 inch(英寸) = 2.54cm = 25.4mm

2:屏幕尺寸

我们通常所说的iPhone5屏幕尺寸为4英寸、iPhone6屏幕尺寸为4.7英寸,指的是显示屏对角线的长度(diagonal)

屏幕尺寸:对角线

3:像素密度PPI

PPI(Pixel Per Inch by diagonal):表示沿着对角线,每英寸所拥有的像素(Pixel)数目。

PPI数值越高,代表显示屏能够以越高的密度显示图像,即通常所说的分辨率越高、颗粒感越弱。

物理尺寸(对角线长度) 像素尺寸(像素总量)

根据勾股定理

iPhone4(s)的PPI计算公式为:

计算结果稍有出入,这是因为像素的离散采样有锯齿效应。


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)

后来在iPhone4中,同样大小(3.5 inch)的屏幕采用了Retina显示技术,横、纵向方向像素密度都被放大到2倍,像素分辨率提高到(320x2)x(480x2)= 960x640(PPI=326), 显像分辨率提升至iPhone3GS的4倍(1个Point被渲染成1个2x2的像素矩阵)。

但是对于开发者来说,iOS绘制图形的API依然沿袭point(pt,注意区分印刷行业的“磅”)为单位。

在同样的逻辑坐标系下(320x480):

1 point = scale*pixel

(在iPhone4~6中,缩放因子scale=2;在iPhone6+中,缩放因子scale=3)。

结论:

scale=绝对长度比(point/pixel)=单位长度内的数量比(pixel/point)


(2)UIScreen.scale

UIScreen.h

@property(nonatomic,readonly)CGFloatscaleNS_AVAILABLE_IOS(4_0);

为了自动适应分辨率,系统会根据设备实际分辨率,自动给UIScreen.scale赋值,该属性对开发者只读。

(3)UIScreen.nativeScale(iOS8新增了nativeScale属性:nativeScale与scale没有太大区别)

@property(nonatomic,readonly)CGFloatnativeScaleNS_AVAILABLE_IOS(8_0);

(4)机型判别

在同样的逻辑分辨率下,可以通过scale参数识别是iPhone3GS还是iPhone4(s)。以下基于nativeScale参数,定义了探测机型是否为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,如何区分机型iPhone4与4s、iPhone5与5s呢?通过[[UIDevice currentDevice] model]只能判别iPhone、iPad、iPod大类,要判断iPhone具体机型型号,则需要通过sysctlbyname("hw.machine")获取详细的设备参数信息予以甄别。


5:@2x @3x及高倍图适配

(1)@2x

iPhone3GS时代,我们为一个应用提供图标(或按钮提供贴图),只需要icon.png。针对现在的iPhone4~6 Retina显示屏,需要制作额外的@2x高分辨率版本。

例如在iPhone3GS中,scale=1,用的图标 50x50pixel(logicalimage.size=50x50point);在iPhone4~6中,scale=2,则需要100×100pixel(logical image.size=50x50point,乘以image.scale=dimensions in pixels),并且命名为icon@2x.png。 

如果APP要同时兼容iPhone3GS~iPhone6,则需要提供icon.png/icon@2x.png两种分辨率的图片。

(2)@3x

Phone6+在实际渲染时,downsampling/1.15(1242x2208->1080x1920),准确的讲,应该是@2.46x。苹果为方便开发者用的是@3x的素材,然后再缩放到@2.46x上。

如果APP要同时兼容iPhone3GS~iPhone6+,则需要提供icon.png/icon@2x.png/icon@3x.png三种分辨率的图片。需要注意的是,iOS APP图标的尺寸和命名都需要遵守相关规范。

参考:一张图帮你看懂 iPhone 6 Plus 屏幕分辨率

(3)加载图片的方式

<1>

+imageNamed:

该方法使用系统缓存,适合表视图重复加载图像的情形。同时该API根据UIScreen的scale,自动查找包含对应高倍图后缀名(@2x)的文件,如果找到二倍图,则image.scale=2.0,对应逻辑size大小以point度量(pixel度量的一半);如果没找到设置默认image.scale=1.0,对应逻辑size大小同像素尺寸。因此,

使用该方法,无需特意指定高倍图后缀。在实际运行时,系统如果发现当前设备是Retina屏(scale=2),会自动寻找"*@2x.png"命名格式的图片,加载针对Retina屏的图片素材,否则会失真。

<2>

+imageWithContentsOfFile

+imageWithData:(scale:)

-initWithContentsOfFile:

-initWithData:(scale:)

这组方法创建的UIImage对象没有使用系统缓存,并且指定文件名必须包含明确的高倍图后缀。

如果文件名包含@2x后缀,则image.scale=2.0;否则默认image.scale=1.0,同样对于Retina屏将会失真。

<3>

目前,适配iPhone6+时,除了一些铺满全屏的大图(LogoIcon、LaunchImage)需提供三倍图,其他的小图仍可沿用原有的二倍图自适应拉伸。


6:Screen Bounds  &  Application Frame

(1) UIScreen.bounds

// Bounds of entire screen in points(本地坐标系,起点为[0,0])

@property(nonatomic,readonly)CGRectbounds;

//考虑 转屏 的影响,按照实际屏幕方向(UIDevice  Orientation)的宽高

#defineSCREEN_WIDTH([UIScreenmainScreen].bounds.size.width)

#defineSCREEN_HEIGHT([UIScreenmainScreen].bounds.size.height)

#defineSTATUSBAR_HEIGHT([UIApplicationsharedApplication].statusBarFrame.size.height)

//不考虑转屏的影响,只取竖屏(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:机型尺寸适配(Screen Scale Adaption)

待续

上一篇下一篇

猜你喜欢

热点阅读