我正在开发一个应用程序,用户可以在其中编辑使用CAShapeLayer
创建的不同形状。一切正常,直到我旋转或翻转形状。当我应用这些转换时,坐标系似乎也发生了变化。此后,其他转换(例如CATransform3DMakeTranslation
)将无法正常工作。
如何重新调整坐标系?是否可以在保持原始坐标系的同时翻转/旋转形状?
这是一个示例,我想将形状旋转45度,然后将其向上移动100点。如果在移动形状之前将其旋转,则该形状将向右而不是向上移动。
class ViewController: UIViewController {
@IBOutlet weak var canvasView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
// Create path
let path = UIBezierPath()
path.move(to: CGPoint(x: canvasView.bounds.midX, y: canvasView.bounds.maxX))
path.addLine(to: CGPoint(x: canvasView.bounds.midX, y: canvasView.bounds.minY))
// Create shape layer
let shapeLayer = CAShapeLayer()
shapeLayer.frame = canvasView.bounds
shapeLayer.path = path.cgPath
shapeLayer.strokeColor = UIColor.black.cgColor
shapeLayer.fillColor = UIColor.clear.cgColor
shapeLayer.lineWidth = 8.0
shapeLayer.lineCap = .round
shapeLayer.lineJoin = .round
canvasView.layer.addSublayer(shapeLayer)
// Add transformations to shape layer
var transform = CATransform3DMakeRotation(0.785398, 0.0, 0.0, 1.0)
transform = CATransform3DTranslate(transform, 0.0, -100.0, 0.0)
shapeLayer.transform = transform
}
}
CATransform3DMakeScale
it返回按sx
,sy
和sz
缩放的变换,其中sx
,sy
和sz
是缩放,乘以x,y和z坐标。当您使用2d对象(例如UIlabel z参数)不会影响您的对象时:
例如,如果要用1/2 x,3 * y转换对象,应编写如下:
myObject.layer.transform = CATransform3DMakeScale(0.5, 3.0, 1.0)
旋转
旋转变换使图层围绕锚点旋转(默认情况下为图层的中心)。基本语法是:
CATransform3DMakeRotation(angle: CGFloat, x: CGFloat, y: CGFloat, z: CGFloat)
其中,角度是弧度,层应旋转的角度,x,y和z是旋转轴。将轴设置为0会取消围绕该特定轴的旋转。
如果我们想将图层顺时针旋转30度,我们将执行以下操作:
let degrees = 30.0
let radians = CGFloat(degrees * M_PI / 180)
myObject.layer.transform = CATransform3DMakeRotation(radians, 0.0, 0.0, 1.0)
您仅可以为每个图层设置一个变换,因此,如果要使用多个变换,则应使用多重变换
** CATransform3DConcat **
为了组合多个变换,我们可以使用像这样的隐喻
CATransform3DConcat(a: CATransform3D, b: CATransform3D)
但是,我们将一个接一个地做。第一个转换将使用Make作为其名称。以下转换将不使用Make,但它们会将先前的转换作为参数。
let firstTransform = CATransform3DMakeScale(0.5, 3.0, 1.5)
let degrees = 30.0
let radians = CGFloat(degrees * M_PI / 180)
let second = CATransform3DMakeRotation(radians, 0.0, 0.0, 1.0)
myObject.layer.transform = CATransform3DConcat(firstTransform, second)
此外,我们可以一个接一个地插入它们作为级联变换层
let degrees = 30.0
let radians = CGFloat(degrees * M_PI / 180)
// translate
var transform = CATransform3DMakeTranslation(90, 50, 0)
// rotate
transform = CATransform3DRotate(transform, radians, 0.0, 0.0, 1.0)
// scale
transform = CATransform3DScale(transform, 0.5, 3.0, 1.0)
// apply the transforms
myObject.layer.transform = transform