Применение масштабирования и поворота к виду с использованием CGAffineTransform - PullRequest
12 голосов
/ 09 ноября 2011

Поэтому мне нужно применить некоторое масштабирование и некоторое вращение к виду (я делаю это с помощью жестов), поэтому для каждого жеста я обновляю текущие значения scalling и вращения с помощью чего-то вроде:

self.scaleWidth *= gesture.scale; //When I detect an horizontal pinch
self.scaleHeight *= gesture.scale; //When I detect a vertical pinch
self.rotationAngle += gesture.rotationAngle; //When I detect a rotation

ЗатемЯ делаю следующее, чтобы преобразовать представление:

CGAffineTransform transform = CGAffineTransformScale(CGAffineTransformIdentity, self.scaleWidth, self.scaleHeight);
self.theSubViewToTransform.transform = CGAffineTransformRotate(transform, self.rotationAngle);

Когда я делаю только масштабирование, оно работает нормально.Когда я делаю масштабирование, а затем вращаюсь, оно вращается нормально.Когда после поворота я пытаюсь снова масштабировать, он не работает нормально: масштаб применяется, как если бы он был сделан после поворота, искажая структуру моего изображения.

Я думал, что сделал то, что нужно было сделать, чтобы избежать этого: начинать каждый раз с преобразования идентичности, сначала масштабируя, а затем вращая, но, очевидно, я ошибался ...

Кто-нибудь знает, что не так с моей реализацией?

Спасибо

Ответы [ 4 ]

11 голосов
/ 11 ноября 2011

Если вы начинаете с преобразования идентичности каждый раз, конечный результат, для которого вы устанавливаете преобразование подпредставления, будет включать только масштабирование и поворот из текущего жеста.Вместо того, чтобы начинать с идентификатора, начните с текущего преобразования представления.

CGAffineTransform transform = self.theSubViewToTransform.transform;
transform = CGAffineTransformScale(transform, self.scaleWidth, self.scaleHeight);
transform = CGAffineTransformRotate(transform, self.rotationAngle);
self.theSubViewToTransform.transform = transform;

При первом выполнении преобразования преобразование запускается как преобразование идентификатора.При последующих выполнениях он будет вносить новые изменения поверх старых.

5 голосов
/ 13 апреля 2017

Для Свифт 3 :

view.transform = CGAffineTransform(rotationAngle:  CGFloat.pi).concatenating(CGAffineTransform(scaleX: 0.4, y: 0.4))
3 голосов
/ 20 июня 2014

Вы должны начать с вашего текущего преобразованного состояния и применить ожидаемое преобразование. Также вы можете взглянуть на CGAffineTransformConcat, он превратится в одно преобразование перед применением.

CGAffineTransform transform = yourView.transform;
transform = CGAffineTransformConcat(CGAffineTransformScale(transform,  self.scaleWidth, self.scaleHeight),
                                    CGAffineTransformRotate(transform, self.rotationAngle));
yourView.transform = transform;

Надеюсь, это поможет!

2 голосов
/ 20 июня 2014

Попробуйте применить преобразования к преобразованию идентичности, например,

CGAffineTransform transform = CGAffineTransformIdentity;
transform = CGAffineTransformScale(transform, scaleWidth, scaleHeight);
transform = CGAffineTransformRotate(transform, angle);
viewToTransform.transform = transform;
...