web-dev-qa-db-ja.com

Swiftで複数の変換を適用する方法

翻訳、回転、スケールなど、UIView(またはUIViewのサブクラス)に複数の変換を適用したいと思います。 CGAffineTransformConcat で2つの変換を適用できることを知っていますが、3つ以上の変換がある場合はどうすればよいですか?

私はこれらの質問を見ました:

しかし、これらの質問は別の質問をしているので、与えられた答えはCGAffineTransformConcatを使用して2つの変換を適用することについて述べています。また、SwiftではなくObjective-Cを使用します。

49
Suragch

複数の変換を重ねて適用できます。

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

この回答 を教えてくれてありがとう。

ノート

  • 変換を適用する順序は重要です。たとえば、変換が逆の順序で実行された場合、次の結果が生成されます。

    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でテストされました。

116
Suragch

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)
26
Tyler Sheaffer