UIKit中如何正确在CALayer上使用透视变换?
CALayer 透视效果正确实现方式
首先明确核心前提:CATransform3D 透视效果的核心是修改矩阵的m34字段,单位矩阵CATransform3DIdentity的m34默认值为0,不会产生任何透视效果,必须手动赋值为-1.0 / 观察距离,观察距离通常取500~1000,数值越大透视变形越平缓,数值越小变形越强烈。
你之前代码不生效的核心原因是:定义的perspective变量没有修改m34值,本质就是无任何效果的单位矩阵,无论赋值给哪个属性都不会产生透视。
两个透视相关属性的适用场景
sublayerTransform和transform的作用范围完全不同,根据需求选择即可:
- 如果你需要给当前视图的所有子视图/子图层统一应用透视规则,子图层各自做3D变换时不需要重复拼接透视矩阵,就用
sublayerTransform
正确示例代码:var perspective = CATransform3DIdentity // 关键:设置透视参数,800是日常开发中比较自然的观察距离 perspective.m34 = -1.0 / 800 // 给当前图层设置子层统一透视 view.layer.sublayerTransform = perspective // 子图层直接设置自身的3D变换即可,不需要额外拼接透视 subView.layer.transform = CATransform3DMakeRotation(.pi/4, 0, 1, 0) - 如果你需要给当前视图/当前图层本身做3D透视变换,
sublayerTransform不会作用于当前图层自身,必须将透视矩阵和目标变换拼接后赋值给transform属性
正确示例代码:var perspective = CATransform3DIdentity perspective.m34 = -1.0 / 800 // 拼接透视矩阵和目标变换,注意矩阵乘法顺序:先执行someTransform,再应用透视 view.layer.transform = CATransform3DConcat(perspective, someTransform)
注意事项
- 矩阵拼接有严格顺序,
CATransform3DConcat(a, b)的执行逻辑是先应用b变换,再应用a变换,透视矩阵需要放在第一个参数位置,避免变换效果错乱 - 不要同时给父子图层重复设置透视矩阵,否则会出现透视叠加、变形异常的问题
内容的提问来源于stack exchange,提问作者sak
相关产品推荐
相关产品推荐

