Как применить несколько преобразований в Swift

Я хотел бы применить несколько преобразований к UIView (или подклассу UIView), таким как перевод, поворот и масштабирование. Я знаю, что два преобразования могут быть применены с CGAffineTransformConcat, но как это сделать, если у меня есть три или более преобразования?

Я видел следующие вопросы:

но эти вопросы задают что-то другое, и в этих ответах просто говорится о применении двух преобразований с помощью CGAffineTransformConcat. Кроме того, они используют Objective-C, а не Swift.

Ответ 1

Вы можете применять несколько преобразований, складывая их друг над другом.

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)
    

введите описание изображения здесь

См. также

Этот ответ был протестирован с помощью Swift 4

Ответ 2

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