When my UIView
is rotated with transform property (CGAffineTransformMakeRotation
), I need to drag one of its corners, say bottom right, to resize it. During this process when user drags the corner, the view's corner must follow user's finger and resize the box by increasing 2 of the sides (right and bottom size for bottom right corner dragging).
It is not so difficult to resize UIView
when you can use frame and touch locations when box is not transformed. For example, I would remember initial frame and touch in UIPanGestureRecognizer
handler
attached to this resizable view on StateBegan, and on StateChanged I would calculate the touch point X, Y difference from initial touch and add those values to initial frame width and height.
However, frame is be reliable for rotated UIView
when transform is applied. Thus I can only rely on bounds
and center
. I created this code but it almost works: I can only enlarge the view proportionally in all 4 directions, not one.
- (void)handleResizeGesture:(UIPanGestureRecognizer *)recognizer {
CGPoint touchLocation = [recognizer locationInView:self.superview];
CGPoint center = self.center;
switch (recognizer.state) {
case UIGestureRecognizerStateBegan: {
deltaAngle = atan2f(touchLocation.y - center.y, touchLocation.x - center.x) - CGAffineTransformGetAngle(self.transform);
initialBounds = self.bounds;
initialDistance = CGPointGetDistance(center, touchLocation);
initialLocation = touchLocation;
if ([self.delegate respondsToSelector:@selector(stickerViewDidBeginRotating:)]) {
[self.delegate stickerViewDidBeginRotating:self];
}
break;
}
case UIGestureRecognizerStateChanged: {
CGFloat scale = CGPointGetDistance(center, touchLocation)/initialDistance;
CGFloat minimumScale = self.minimumSize/MIN(initialBounds.size.width, initialBounds.size.height);
scale = MAX(scale, minimumScale);
CGRect scaledBounds = CGRectScale(initialBounds, scale, scale);
self.bounds = scaledBounds;
[self setNeedsDisplay];
if ([self.delegate respondsToSelector:@selector(stickerViewDidChangeRotating:)]) {
[self.delegate stickerViewDidChangeRotating:self];
}
break;
}
case UIGestureRecognizerStateEnded:
if ([self.delegate respondsToSelector:@selector(stickerViewDidEndRotating:)]) {
[self.delegate stickerViewDidEndRotating:self];
}
break;
default:
break;
}
}
Image below shows the rotated view with known values (A, B, x, y, N, M, N-M distance):