如何在Swift中应用多个转换

Sur*_*gch 49 transform uiview cgaffinetransform ios swift

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

我看过这些问题:

但是这些问题正在问一些不同的东西,给出的答案只是谈论应用两个变换CGAffineTransformConcat.此外,他们使用Objective-C而不是Swift.

Sur*_*gch 117

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

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
Run Code Online (Sandbox Code Playgroud)

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

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

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

在此输入图像描述

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

笔记

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

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

在此输入图像描述

也可以看看

这个答案已经使用Swift 4进行了测试


Tyl*_*fer 26

在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
}
Run Code Online (Sandbox Code Playgroud)

所以例如

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