iOS CoreAnimation(二)contentsRect, contentsCenter

本文详细介绍了iOS中CALayer的contentsRect和contentsCenter属性的应用。通过实例展示了如何利用contentsRect实现图片裁剪以提高游戏性能,以及如何利用contentsCenter控制图片拉伸,确保特定区域不变形。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先拓展一下上篇文章说的点与像素:

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

    }

}

 
效果:在两种尺寸的“屏幕”上,黄色区域形状是相同的,没有变形
 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值