1
votes

I have a view, which the user can scale and rotate through UIGestureRecognizer. This view contains two views:

 superview
  - content
  - button

The content should be scaled and rotated, and the button should keep it's size and position.
I'am scaling and rotating the views with help of CGAffineTransform and UIGestureRecognizer.


How can I achieve this?

I've tried:

  • to scale/rotate the superview and reset the button transform and position. No success.
  • to scale/rotate the content and try to set the content.frame.size to the superview. No success. (Although I think this has to work somehow).
  • and some obscure bad things, which are not worth to mention.

Edit:

The code which handles the rotating and scaling:

if ([recognizer respondsToSelector:@selector(rotation)]) {
    CGFloat rotation = 0.0f - (self.lastRotation - [(UIRotationGestureRecognizer *) recognizer rotation]);

    CGAffineTransform currentTransform = self.content.transform;
    CGAffineTransform newTransform = CGAffineTransformRotate(currentTransform, rotation);
    self.content.transform = newTransform;

    self.lastRotation = [(UIRotationGestureRecognizer *) recognizer rotation];

} else if ([recognizer respondsToSelector:@selector(scale)]) {
    CGFloat scale = 1.0f - (self.lastScale - [(UIPinchGestureRecognizer *) recognizer scale]);

    CGAffineTransform currentTransform = self.content.transform;
    CGAffineTransform newTransform = CGAffineTransformScale(currentTransform, scale, scale);
    self.content.transform = newTransform;

    self.lastScale = [(UIPinchGestureRecognizer *) recognizer scale];
}

Just basic scaling and rotating, nothing fancy.

1
Using bullet item two: after scaling/rotating the content, why are you changing the content.frame.size? Note that the content.frame is the smallest rectangle that encloses the view, so it's tricky to use on a view that's been rotated. You can use the center and bounds properties to move and scale the view, and use the transform to rotate the view around its center.user3386109
If I scale the content the bounds doesn't change. I set just the size, because the content will have different x and y coordinates, than the superview. The superview can be moved around in it's parent view. The scaling and resizing itself is done by using CGAffineTransform.Leandros
Is the content a single view with no subviews, or is it multiple views and/or subviews?user3386109
content is just a single UIImageView.Leandros
So my suggestion is to use bounds.size to scale the view, use transform only for rotation, and use the center property to position the view properly in the superview.user3386109

1 Answers

1
votes

The actual solution:

if ([recognizer respondsToSelector:@selector(rotation)]) {
    CGFloat rotation = 0.0f - (self.lastRotation - [(UIRotationGestureRecognizer *) recognizer rotation]);

    CGAffineTransform currentTransform = self.transform;
    CGAffineTransform newTransform = CGAffineTransformRotate(currentTransform, rotation);
    self.transform = newTransform;

    self.lastRotation = [(UIRotationGestureRecognizer *) recognizer rotation];

} else if ([recognizer respondsToSelector:@selector(scale)]) {
    CGFloat scale = 1.0f - (self.lastScale - [(UIPinchGestureRecognizer *) recognizer scale]);

    CGRect bounds = self.bounds;
    bounds.size.width *= scale;
    bounds.size.height *= scale;
    self.bounds = bounds;

    self.lastScale = [(UIPinchGestureRecognizer *) recognizer scale];
}