如何在Swift中应用多个转换

时间:2015-06-19 04:37:47

标签: ios swift uiview transform cgaffinetransform

我想将多个变换应用于UIView(或UIView的子类),例如平移,旋转和缩放。我知道可以使用CGAffineTransformConcat应用两个变换,但如果我有三个或更多变换,我该怎么做呢?

我见过这些问题:

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

2 个答案:

答案 0 :(得分:105)

您可以通过将多个变换堆叠在一起来应用它们。

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)

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

enter image description here

感谢this answer教我如何做。

注释

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

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

enter image description here

另见

此答案已使用Swift 4

进行了测试

答案 1 :(得分:25)

在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)