先拓展一下上篇文章说的点与像素:
iOS使用了以下坐标系统:
1、
(PS:iPhoneX、Xs、11 Pro 等开始出现 1点对应3像素,面积上就是3*3,以后肯定有更高ppi的屏幕)
2、
3、
(PS:单位坐标,简单来说就是 0~1,表示一个相对位置)
一、CALayer 的 contentsRect 属性 允许我们在图层边框里显示寄宿图的一个子范围
它使用了单位坐标 0~1 ,默认 {0, 0, 1, 1} ,表示从(0,0)开始,宽高为(1,1)的区域被显示。如果指定为 {0, 0, 0.5, 0.5},效果如下图,被裁减的范围会被显示在屏幕上
用途呢?主要是游戏编程中,为了提高性能,多张图片被拼成一张图,这样只需要从硬盘读取一次,对象只有一个,渲染方面也有好处···
例如,我只有一张图片,注意是一张:
从硬盘读取一次,一个 UIImage 对象,然后通过设置 contentsRect 实现如下效果:
主要是游戏编程中用,有些第三方库专门弄这个,下面是 demo 源码
import UIKit
class ViewController: UIViewController {
var view1:UIView!
var view2:UIView!
var view3:UIView!
var view4:UIView!
///myView 的大小
let size:CGFloat = 100
///屏幕的宽度
let width = UIScreen.main.bounds.width
///屏幕的高度
let height = UIScreen.main.bounds.height
override func viewDidLoad() {
super.viewDidLoad()
//frame随便敲
view1 = UIView(frame: CGRect(x: 20, y: 50, width: size, height: size))
view2 = UIView(frame: CGRect(x: 150, y: 250, width: size, height: size))
view3 = UIView(frame: CGRect(x: 40, y: 380, width: size, height: size))
view4 = UIView(frame: CGRect(x: 180, y: 520, width: size, height: size))
let img = UIImage(named: "bigImg.png")!
//方法在下面
view1.addImage(img: img, withContent: CGRect(x: 0, y: 0, width: 0.5, height: 0.5))
view2.addImage(img: img, withContent: CGRect(x: 0.5, y: 0.5, width: 0.5, height: 0.5))
view3.addImage(img: img, withContent: CGRect(x: 0, y: 0.5, width: 0.5, height: 0.5))
view4.addImage(img: img, withContent: CGRect(x: 0.5, y: 0, width: 0.5, height: 0.5))
view.addSubview(view1)
view.addSubview(view2)
view.addSubview(view3)
view.addSubview(view4)
}
}
extension UIView {
func addImage(img:UIImage,withContent rect:CGRect){
layer.contents = img.cgImage
layer.contentsGravity = kCAGravityResizeAspect
layer.contentsRect = rect
}
}
二、 contentsCenter 属性 :控制寄宿图的拉伸
layer.contentsGravity 不是已经控制了拉伸了吗?比如 拉伸变形来填充、拉伸保持形状填充、拉伸保持形状及图片完整但不填充等,这是对寄宿图整体的控制,但如果我想让寄宿图拉伸时,图片的某个区域永远保持原形状,其余的随意拉伸呢?
contentsCenter 这个名字有误导性,不要理解它的英语意思,默认值 { 0, 0, 1, 1 },我先用一个值 { 0.25, 0.25, 0.5, 0.5 } 介绍它的功能。如下左图,起点(0.25,0.25),宽高(0.5,0.5),它实际把图层划分为了3*3,9个区域,如右图。当 contentsGravity 设置允许拉伸时,这9个区域,有着自己的拉伸办法。四个角,保持原样;蓝色只会水平拉伸,红色只垂直拉伸,绿色两个方向都拉伸。
用途呢?假设 设计师要求下面这张图作为界面的背景图片,要适配不同尺寸的屏幕进行拉伸,但是四个角必须是正方形,不允许变形。假设不用 contentsCenter 属性,最容易想到的是用多个图片,多个视图,写约束代码。。。。想想就麻烦
demo :
import UIKit
class ViewController: UIViewController {
var view1:UIView!
var view2:UIView!
let size:CGFloat = 100
///屏幕的宽度
let width = UIScreen.main.bounds.width
///屏幕的高度
let height = UIScreen.main.bounds.height
override func viewDidLoad() {
super.viewDidLoad()
// 假设这两个 view 就代表不同的设备屏幕,尺寸不一样
view1 = UIView(frame: CGRect(x: 40, y: 50, width: size, height: size*2))
view2 = UIView(frame: CGRect(x: 150, y: 450, width: 2.4*size, height: 1.2*size))
let img = UIImage(named: "big.png")!
let rect = CGRect(x: 0.25, y: 0.25, width: 0.5, height: 0.5)
view1.addStretchableImage(img: img, withCenter: rect)
view2.addStretchableImage(img: img, withCenter: rect)
view.addSubview(view1)
view.addSubview(view2)
}
}
extension UIView {
func addStretchableImage(img:UIImage,withCenter rect:CGRect){
layer.contents = img.cgImage
layer.contentsCenter = rect
}
}
