Как переместить UIImageView после применения CGAffineTransformRotate к нему? - PullRequest
5 голосов
/ 01 февраля 2011

Я создаю приложение для iPhone. У меня есть UIView, который содержит набор объектов подкласса UIImageView. Пользователь может перетаскивать и поворачивать изображения с помощью касания. У меня возникают проблемы при перемещении изображения после его поворота.

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

CGAffineTransform trans = self.transform;
self.transform = CGAffineTransformRotate(trans, delta);

Проблема возникает позже, когда пользователь пытается переместить элемент касанием. В touchesBegan: WithEvent :, я сохраняю начальную точку в переменной класса, startLocation:

- (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{   
    // Retrieve the touch point
    CGPoint pt = [[touches anyObject] locationInView:self];
    startLocation = pt;
}

В touchesMoved: withEvent :, у меня был следующий код, который работает достаточно хорошо, если в представлении изображения нет преобразования вращения:

- (void) touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
{
    CGPoint pt = [[touches anyObject] locationInView:self];
    CGFloat dx = pt.x - startLocation.x;
    CGFloat dy = pt.y - startLocation.y;
    CGPoint newCenter = CGPointMake(self.center.x + dx, self.center.y + dy);
    self.center = newCenter;
}

Но если при просмотре изображения происходит преобразование поворота, то при каждом событии touchSMoved оно отображается по экрану и вскоре исчезает. В отладчике я заметил, что значение pt стало чудовищным. Мне пришло в голову, что мне нужно преобразовать эту точку, что я и сделал, вот так:

- (void) touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
{
CGPoint pt = [[touches anyObject] locationInView:self];
if (!CGAffineTransformIsIdentity(self.transform)) {
    pt = CGPointApplyAffineTransform(pt, self.transform);
}

CGFloat dx = pt.x - startLocation.x;
CGFloat dy = pt.y - startLocation.y;
CGPoint newCenter = CGPointMake(self.center.x + dx, self.center.y + dy);
}

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

Как я могу переместить изображение без начального толчка?

Почему мне не нужно преобразовывать startLocation (точку, которую я фиксирую, когда начинается касание)?

Ответы [ 2 ]

1 голос
/ 07 марта 2011
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)_event {
    CGPoint pt = [[touches anyObject] locationInView:self]; 
    startLocation = pt;
} 

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)_event {
    CGPoint pt = [[touches anyObject] previousLocationInView:self];
    CGFloat dx = pt.x - startLocation.x;
    CGFloat dy = pt.y - startLocation.y;
    CGPoint newCenter = CGPointMake(self.center.x + dx, self.center.y + dy);
    self.center = newCenter;
}

- (void)setRotation:(float)rotation {
    self.transform = CGAffineTransformRotate(self.transform, degreesToRadians(rotation));
}
0 голосов
/ 01 февраля 2011

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

Взгляните на метод UIView "convertPoint: toView:" :

convertPoint: toView:

Преобразует точку из системы координат получателя в систему координат указанного вида.

- (CGPoint) convertPoint: (CGPoint) точка toView: (UIView *) представление

Параметры

точка

Точка, указанная в локальной системе координат (границ) приемника.

вид

Вид, в точку которого система координат должна быть преобразована. Если view равен nil, этот метод вместо этого преобразует в базовые координаты окна. В противном случае и представление, и получатель должны принадлежать одному и тому же объекту UIWindow.

Возвращаемое значение

Точка, преобразованная в систему координат зрения.

Обновление:

В ответ на комментарии:

Вы должны получить «реальные» координаты касания пальцем (в не повернутой системе), тогда, когда палец перемещается, у вас всегда появляются новые координаты в главном не повернутом виде: и это точка, которую вы должны преобразовать в повернутый вид родительский вид, который вы перемещаете.

  • Если A - это mainView 320x480 pixel
  • и B - это подвид 320x480 пикселей с центром в A ,
  • и C - это подвид в B в положении 170,240 ( + 10, + 0 центра экрана)
  • и вы поворачиваете B из 90 градусов по часовой стрелке
  • затем C по-прежнему в 170,240 в B

Но вы видите это в 160,250 на экране,

и если теперь пользователь хочет переместить его + 20 вправо, пользователь перемещает палец + 20 в координатах экрана, а не в B просмотр координат, поэтому пользователь хотел бы видеть его на 180,250 экрана, это означает, что вам нужно преобразовать эту точку в B систему координат ...

Так что это немного проще, вам просто нужно получить экранные координаты пальца, когда пользователь перемещает его, и просто преобразовать его в координаты с вращающимся обзором ( B ) ...

...