如何在Swift中应用多个转换

我想应用多个转换到UIView (或UIView子类),如翻译,旋转和缩放。 我知道两个转换可以与CGAffineTransformConcat ,但是如果我有三个或更多的转换,我该怎么做呢?

我看到了这些问题:

  • 将多个转换应用于UIView / CALayer
  • 在文本matrix上使用多个CGAffineTransforms

但是这些问题提出了不同的问题,给出的答案只是讨论了使用CGAffineTransformConcat进行两次转换。 另外,他们使用Objective-C而不是Swift。

您可以将多个转换叠加在一起应用。

 var t = CGAffineTransform.identity t = t.translatedBy(x: 100, y: 300) t = t.rotated(by: CGFloat.pi / 4) t = t.scaledBy(x: -1, y: 2) // ... add as many as you want, then apply it to to the view imageView.transform = t 

或更紧凑(但不一定可读):

 imageView.transform = CGAffineTransform.identity.translatedBy(x: 100, y: 300).rotated(by: CGFloat.pi / 4).scaledBy(x: -1, y: 2) 

这一系列变换产生了右边的图像:

在这里输入图像说明

感谢这个答案 ,教我如何做到这一点。

笔记

  • 您应用转换的顺序很重要。 例如,如果转换是按照相反的顺序完成的,则会产生以下结果。

     t = t.scaledBy(x: -1, y: 2) t = t.rotated(by: CGFloat.pi / 4) t = t.translatedBy(x: 100, y: 300) 

在这里输入图像说明

也可以看看

  • CGAffineTransform参考 (docs)
  • 转换 (文档)
  • Swift:翻译和旋转CGContext,一个可视的解释(iOS / Xcode)
  • 解密CGAffineTransform

这个答案已经用Swift 4testing过了

在Swift 3中,这些被CGAffineTransform本身的函数所取代,可以链接在一起。

 extension CGAffineTransform { public func translatedBy(x tx: CGFloat, y ty: CGFloat) -> CGAffineTransform public func scaledBy(x sx: CGFloat, y sy: CGFloat) -> CGAffineTransform public func rotated(by angle: CGFloat) -> CGAffineTransform } 

所以例如

 let transform = CGAffineTransform(scaleX: 1.0, y: 3.0).translatedBy(x: 12, y: 9).rotated(by: 17.0)