在 iPhone 中使用 UIPanGesture 旋转 UIView 的框架增加减少
Posted
技术标签:
【中文标题】在 iPhone 中使用 UIPanGesture 旋转 UIView 的框架增加减少【英文标题】:Rotated UIView's frame Increase Decrease with UIPanGesture in iPhone 【发布时间】:2012-10-16 13:06:59 【问题描述】:我创建了一个 UIView,应用 UIPanGestureRecognizer 用一根手指旋转,也用一根手指增加和减少它的框架。
旋转视图放在 UIView 的左下角。 调整 UIView 右下角的视图大小。让我写下它的一些代码行。
//Rotate Apply with Pan Gesture
panRotateGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(rotateViewPanGesture:)];
[rotateView addGestureRecognizer:panRotateGesture];
//Resize View Apply with Pan Gesture
panResizeGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(resizeTranslate:)];
[resizeView addGestureRecognizer:panResizeGesture];
[panRotateGesture requireGestureRecognizerToFail:panResizeGesture];
这是用一根手指用 UIPanGesture 调整视图大小的方法。
-(void)resizeTranslate:(UIPanGestureRecognizer *)recognizer
if ([recognizer state]== UIGestureRecognizerStateBegan)
prevPoint = [recognizer locationInView:self.superview];
[self setNeedsDisplay];
else if ([recognizer state] == UIGestureRecognizerStateChanged)
if (self.frame.size.width < kFixW)
self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, kFixW, self.frame.size.height);
if(self.frame.size.height < kFixH)
self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, kFixH);
CGPoint point = [recognizer locationInView:self.superview];
float wChange = 0.0, hChange = 0.0;
wChange = (point.x - prevPoint.x); //Slow down increment
hChange = (point.y - prevPoint.y); //Slow down increment
self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width + (wChange), self.frame.size.height + (hChange));
NSLog(@"self.frame : %@",NSStringFromCGRect(self.frame));
prevPoint = [recognizer locationInView:self.superview];
[self setNeedsDisplay];
else if ([recognizer state] == UIGestureRecognizerStateEnded)
prevPoint = [recognizer locationInView:self.superview];
[self setNeedsDisplay];
如果用一根手指用 UIPanGesture 旋转 UIView
-(void)rotateViewPanGesture:(UIPanGestureRecognizer *)recognizer
if ([recognizer state] == UIGestureRecognizerStateBegan)
deltaAngle = atan2([recognizer locationInView:self].y-self.center.y, [recognizer locationInView:self].x-self.center.x);
startTransform = self.transform;
else if ([recognizer state] == UIGestureRecognizerStateChanged)
float ang = atan2([recognizer locationInView:self.superview].y - self.center.y, [recognizer locationInView:self.superview].x - self.center.x);
float angleDiff = deltaAngle - ang;
self.transform = CGAffineTransformMakeRotation(-angleDiff);
[self setNeedsDisplay];
else if ([recognizer state] == UIGestureRecognizerStateEnded)
float ang = atan2([recognizer locationInView:self.superview].y - self.center.y, [recognizer locationInView:self.superview].x - self.center.x);
deltaAngle = atan2([recognizer locationInView:self].y-self.center.y, [recognizer locationInView:self].x-self.center.x);
startTransform = self.transform;
[self setNeedsDisplay];
现在的问题是, 调整大小和旋转手势都可以正常工作。
当我使用 panResizeGesture 调整视图大小时,它可以正常工作,但是如果我应用一次 panRotateGesture 并且想要应用 panResizeGesture 它会超出屏幕并且无法正常工作。
请有任何解决此问题的想法。
非常感谢。
【问题讨论】:
【参考方案1】:documentation 明确表示:
**如果变换属性不是恒等变换,则该属性的值是未定义的,因此应该被忽略。
如果transform 属性包含非身份转换,则frame 属性的值未定义且不应修改。在这种情况下,您可以使用 center 属性重新定位视图并使用 bounds 属性调整大小。**
所以,只需在 rotateViewPanGesture 方法中将 self.frame 改为 self.bounds
例如
self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, kFixH);
到:
self.bounds = CGRectMake(self.bounds.origin.x, self.bounds.origin.y, self.bounds.size.width, kFixH);
您的代码将完美运行。
更新
我附上了使用您的代码的示例项目。你可以使用这个代码 Answer
【讨论】:
是的。我也有同样的问题,我按照上面的方法解决了 我试过你的代码。一切正常。将框架更改为边界后,您可以发布您的 resizeTranslate 方法吗 我浪费了我的生命来找到那个清晰的文件。谢谢。【参考方案2】:我知道这有点晚了,所以也许您已经想通了,但是您的问题在于 locationInView: 部分代码。当您确实想要计算超级视图的 locationInView 时,您正在尝试计算您尝试旋转的实际视图的 locationInView。
-(void)rotateViewPanGesture:(UIPanGestureRecognizer *)recognizer
if ([recognizer state] == UIGestureRecognizerStateBegan)
deltaAngle = atan2([recognizer locationInView:self.superview].y-self.center.y, [recognizer locationInView:self.superview].x-self.center.x); //here change it to self.superview
startTransform = self.transform;
else if ([recognizer state] == UIGestureRecognizerStateChanged)
float ang = atan2([recognizer locationInView:self.superview].y - self.center.y, [recognizer locationInView:self.superview].x - self.center.x);
float angleDiff = deltaAngle - ang;
self.transform = CGAffineTransformMakeRotation(-angleDiff);
[self setNeedsDisplay];
else if ([recognizer state] == UIGestureRecognizerStateEnded)
float ang = atan2([recognizer locationInView:self.superview].y - self.center.y, [recognizer locationInView:self.superview].x - self.center.x);
deltaAngle = atan2([recognizer locationInView:self.superview].y-self.center.y, [recognizer locationInView:self.superview].x-self.center.x); //here change it to locationInView:self.superview
startTransform = self.transform;
[self setNeedsDisplay];
【讨论】:
以上是关于在 iPhone 中使用 UIPanGesture 旋转 UIView 的框架增加减少的主要内容,如果未能解决你的问题,请参考以下文章
使用 UIPanGesture 将图像的位置存储到 Objc 中 UIView 中的新位置
Swift 中的 UIScrollView 内的 UIPanGesture