一. 什么是scale factor
在[UIScreen mainScreen]
中有个属性叫做scale
,这个属性全称为scale factor
,即比例因子.这个属性代表了从逻辑坐标系
转化成当前的设备坐标系
的转化比例. UIKit
框架中的view
都有一个contentScaleFactor
的属性,表达的意义一样.
逻辑坐标系
即我们数学上经常用的坐标体系,是对现实事物的一种抽象.比如说我们要在app上显示一个正方形,我们会确定它的坐标(100,100)和宽高(100,100).在这里,坐标和宽高的数值都是对这个正方形的一种抽象.在实际显示的过程中,坐标的具体位置和宽高的实际长度则由具体硬件的物理属性和它规定的坐标体系进行表达.在逻辑坐标系
中,以points
作为测量单位,即通常在数学的坐标系中用点
来表示最小的测量单位.
在我们进行编程时,frame
,center
中设置的表达坐标位置所使用的CGFloat
参数就是以point
为单位的.
设备坐标系
是设备实际的坐标系.在实际屏幕中,是以像素
(Pixel
)作为基本的测量单位.
由于两个坐标系的单位不统一,这时需要进行坐标系的转换.
iOS中当我们使用Quartz,UIKit,CoreAnimation等框架时,所有的坐标系统采用Point来衡量.系统在实际渲染到设置时会帮助我们处理Point到Pixel的转换.
二. 坐标系的转换
scale
属性反映了从逻辑坐标到设备屏幕坐标的转换.在非视网膜屏幕上,比例因子值为1.0,即逻辑坐标系中的一个点
等于设备中一个像素(1×1)
,在视网膜屏幕中,比例因子值为2.0,即逻辑坐标系中的一个点
等于设备中四个像素(2×2)
.同理,在6plus这种scale
为3.0的设备上,1point
等于9pixels
.
因此,当我们在绘图中做出一条线宽为1的线时,在非视网膜屏幕和视网膜屏幕上的情况是不同的.
非视网膜屏幕和视网膜屏幕上一个线宽时的显示情况
在非视网膜屏幕中,当我们把线宽为1的线画在(3,0)上时,线为一个像素点
的宽度(虚线部分),由于事实上不能让一个像素点
显示半个像素
,所以iOS的反锯齿
技术让1个线宽的线显示出了2个像素
宽度的一条线(浅色部分),并且颜色变浅.只有对线进行0.5的偏移才能显示真正的线宽为1的线.
偏移了0.5(point)才能显示一个像素宽度的线
在视网膜屏幕中,如果想要画出宽度为一个像素
的线,不仅需要先0.5point的线宽,还要进行0.25point的偏移,才能绘出一个像素点
宽度的线.
当然,如果没有特殊的需求,苹果不建议使用宽度为一个像素点
的线,因为在视网膜屏幕上太细会看不清楚.