如何使用 GestureRecongnizers 阻止 UIImageView 在 UIView 之外移动?
我正在创建一个基于图像的应用程序,我希望显示的图像在我创建的 UIView 中旋转/移动/缩放。我遵循了有关如何实现 UIGestures 的有用在线教程,并且掌握了使用它们的窍门,我只需要更多地了解它们背后的代码,以便我可以在此 UIView 中保留手势。这是代码:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
image = [info objectForKey:@"UIImagePickerControllerOriginalImage"];
layoutOne = [[UIView alloc] initWithFrame:CGRectMake(95.0, 107.0, 578, 682)];
theImageView = [[UIImageView alloc] initWithFrame:[layoutOne frame]];
[theImageView setImage:image];
theImageView.userInteractionEnabled = TRUE;
[layoutOne addSubview:theImageView];
takePhoto.hidden = YES;
theImageView.clipsToBounds = YES;
UIPinchGestureRecognizer *pinchRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(scale:)];
[pinchRecognizer setDelegate:self];
[theImageView addGestureRecognizer:pinchRecognizer];
UIRotationGestureRecognizer *rotationRecognizer = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotate:)];
[rotationRecognizer setDelegate:self];
[theImageView addGestureRecognizer:rotationRecognizer];
UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(move:)];
[panRecognizer setMinimumNumberOfTouches:1];
[panRecognizer setMaximumNumberOfTouches:1];
[panRecognizer setDelegate:self];
[theImageView addGestureRecognizer:panRecognizer];
UITapGestureRecognizer *deleteButton = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(delButton:)];
[deleteButton setNumberOfTapsRequired:2];
[deleteButton setDelegate:self];
[theImageView addGestureRecognizer:deleteButton];
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapped:)];
[tapRecognizer setNumberOfTapsRequired:1];
[tapRecognizer setDelegate:self];
[tapRecognizer requireGestureRecognizerToFail:deleteButton];
[theImageView addGestureRecognizer:tapRecognizer];
[self.view addSubview:theImageView];
}
注意
UIImage *image;
UIImageView *theImageView;
UIView *layoutOne;
这些是我声明的手势识别器,下面是我为让它们完成工作而遵循的教程的另一部分:
-(void)scale:(id)sender {
NSLog(@"See a pinch gesture");
[self.view bringSubviewToFront:[(UIPinchGestureRecognizer*)sender view]];
if([(UIPinchGestureRecognizer*)sender state] == UIGestureRecognizerStateEnded) {
lastScale = 1.0;
return;
}
CGFloat scale = 1.0 - (lastScale - [(UIPinchGestureRecognizer*)sender scale]);
CGAffineTransform currentTransform = [(UIPinchGestureRecognizer*)sender view].transform;
CGAffineTransform newTransform = CGAffineTransformScale(currentTransform, scale, scale);
[[(UIPinchGestureRecognizer*)sender view] setTransform:newTransform];
lastScale = [(UIPinchGestureRecognizer*)sender scale];
}
-(void)rotate:(id)sender {
NSLog(@"See a rotate gesture");
[self.view bringSubviewToFront:[(UIRotationGestureRecognizer*)sender view]];
if([(UIRotationGestureRecognizer*)sender state] == UIGestureRecognizerStateEnded) {
lastRotation = 0.0;
return;
}
CGFloat rotation = 0.0 - (lastRotation - [(UIRotationGestureRecognizer*)sender rotation]);
CGAffineTransform currentTransform = [(UIPinchGestureRecognizer*)sender view].transform;
CGAffineTransform newTransform = CGAffineTransformRotate(currentTransform,rotation);
[[(UIRotationGestureRecognizer*)sender view] setTransform:newTransform];
lastRotation = [(UIRotationGestureRecognizer*)sender rotation];
}
-(void)move:(id)sender {
NSLog(@"See a move gesture");
[[(UITapGestureRecognizer*)sender view] layer];//removeAllAnimations];
[self.view bringSubviewToFront:[(UIPanGestureRecognizer*)sender view]];
CGPoint translatedPoint = [(UIPanGestureRecognizer*)sender translationInView:self.view];
if([(UIPanGestureRecognizer*)sender state] == UIGestureRecognizerStateBegan) {
firstX = [[sender view] center].x;
firstY = [[sender view] center].y;
}
translatedPoint = CGPointMake(firstX+translatedPoint.x, firstY+translatedPoint.y);
[[sender view] setCenter:translatedPoint];
if([(UIPanGestureRecognizer*)sender state] == UIGestureRecognizerStateEnded) {
CGFloat finalX = translatedPoint.x + (.35*[(UIPanGestureRecognizer*)sender velocityInView:self.view].x);
CGFloat finalY = translatedPoint.y + (.35*[(UIPanGestureRecognizer*)sender velocityInView:self.view].y);
if(UIDeviceOrientationIsPortrait([[UIDevice currentDevice] orientation])) {
if(finalX < 0) {
finalX = 0;
}
else if(finalX > 768) {
finalX = 768;
}
if(finalY < 0) {
finalY = 0;
}
else if(finalY > 1024) {
finalY = 1024;
}
}
else {
if(finalX < 0) {
finalX = 0;
}
else if(finalX > 1024) {
finalX = 768;
}
if(finalY < 0) {
finalY = 0;
}
else if(finalY > 768) {
finalY = 1024;
}
}
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:.35];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[[sender view] setCenter:CGPointMake(finalX, finalY)];
[UIView commitAnimations];
}
}
对于我只想制作的长行代码感到抱歉确保您准确理解我想要实现的目标。我想更好地理解主要在 -(void)move:(id)sender
中发生的数学,这样我也许能够阻止 UIImage/UIImageView 移动到 UI 子视图 (layoutOne) 之外我创建的。如果您能帮助我,我将不胜感激!谢谢。
I'm creating an image Based app and I want the images that are displayed to be rotated/moved/scaled within the UIView that i've created. I followed a useful tutorial online on how to implement UIGestures and I've got the hang of using them I just need to understand the code behind them a bit more so I can retain the gestures within this UIView. here is the Code:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
image = [info objectForKey:@"UIImagePickerControllerOriginalImage"];
layoutOne = [[UIView alloc] initWithFrame:CGRectMake(95.0, 107.0, 578, 682)];
theImageView = [[UIImageView alloc] initWithFrame:[layoutOne frame]];
[theImageView setImage:image];
theImageView.userInteractionEnabled = TRUE;
[layoutOne addSubview:theImageView];
takePhoto.hidden = YES;
theImageView.clipsToBounds = YES;
UIPinchGestureRecognizer *pinchRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(scale:)];
[pinchRecognizer setDelegate:self];
[theImageView addGestureRecognizer:pinchRecognizer];
UIRotationGestureRecognizer *rotationRecognizer = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotate:)];
[rotationRecognizer setDelegate:self];
[theImageView addGestureRecognizer:rotationRecognizer];
UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(move:)];
[panRecognizer setMinimumNumberOfTouches:1];
[panRecognizer setMaximumNumberOfTouches:1];
[panRecognizer setDelegate:self];
[theImageView addGestureRecognizer:panRecognizer];
UITapGestureRecognizer *deleteButton = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(delButton:)];
[deleteButton setNumberOfTapsRequired:2];
[deleteButton setDelegate:self];
[theImageView addGestureRecognizer:deleteButton];
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapped:)];
[tapRecognizer setNumberOfTapsRequired:1];
[tapRecognizer setDelegate:self];
[tapRecognizer requireGestureRecognizerToFail:deleteButton];
[theImageView addGestureRecognizer:tapRecognizer];
[self.view addSubview:theImageView];
}
NOTE
UIImage *image;
UIImageView *theImageView;
UIView *layoutOne;
Those are my declared Gesture Recognisers and below is another part of the tutorial I followed to get them to do their jobs:
-(void)scale:(id)sender {
NSLog(@"See a pinch gesture");
[self.view bringSubviewToFront:[(UIPinchGestureRecognizer*)sender view]];
if([(UIPinchGestureRecognizer*)sender state] == UIGestureRecognizerStateEnded) {
lastScale = 1.0;
return;
}
CGFloat scale = 1.0 - (lastScale - [(UIPinchGestureRecognizer*)sender scale]);
CGAffineTransform currentTransform = [(UIPinchGestureRecognizer*)sender view].transform;
CGAffineTransform newTransform = CGAffineTransformScale(currentTransform, scale, scale);
[[(UIPinchGestureRecognizer*)sender view] setTransform:newTransform];
lastScale = [(UIPinchGestureRecognizer*)sender scale];
}
-(void)rotate:(id)sender {
NSLog(@"See a rotate gesture");
[self.view bringSubviewToFront:[(UIRotationGestureRecognizer*)sender view]];
if([(UIRotationGestureRecognizer*)sender state] == UIGestureRecognizerStateEnded) {
lastRotation = 0.0;
return;
}
CGFloat rotation = 0.0 - (lastRotation - [(UIRotationGestureRecognizer*)sender rotation]);
CGAffineTransform currentTransform = [(UIPinchGestureRecognizer*)sender view].transform;
CGAffineTransform newTransform = CGAffineTransformRotate(currentTransform,rotation);
[[(UIRotationGestureRecognizer*)sender view] setTransform:newTransform];
lastRotation = [(UIRotationGestureRecognizer*)sender rotation];
}
-(void)move:(id)sender {
NSLog(@"See a move gesture");
[[(UITapGestureRecognizer*)sender view] layer];//removeAllAnimations];
[self.view bringSubviewToFront:[(UIPanGestureRecognizer*)sender view]];
CGPoint translatedPoint = [(UIPanGestureRecognizer*)sender translationInView:self.view];
if([(UIPanGestureRecognizer*)sender state] == UIGestureRecognizerStateBegan) {
firstX = [[sender view] center].x;
firstY = [[sender view] center].y;
}
translatedPoint = CGPointMake(firstX+translatedPoint.x, firstY+translatedPoint.y);
[[sender view] setCenter:translatedPoint];
if([(UIPanGestureRecognizer*)sender state] == UIGestureRecognizerStateEnded) {
CGFloat finalX = translatedPoint.x + (.35*[(UIPanGestureRecognizer*)sender velocityInView:self.view].x);
CGFloat finalY = translatedPoint.y + (.35*[(UIPanGestureRecognizer*)sender velocityInView:self.view].y);
if(UIDeviceOrientationIsPortrait([[UIDevice currentDevice] orientation])) {
if(finalX < 0) {
finalX = 0;
}
else if(finalX > 768) {
finalX = 768;
}
if(finalY < 0) {
finalY = 0;
}
else if(finalY > 1024) {
finalY = 1024;
}
}
else {
if(finalX < 0) {
finalX = 0;
}
else if(finalX > 1024) {
finalX = 768;
}
if(finalY < 0) {
finalY = 0;
}
else if(finalY > 768) {
finalY = 1024;
}
}
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:.35];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[[sender view] setCenter:CGPointMake(finalX, finalY)];
[UIView commitAnimations];
}
}
Sorry about the long lines of the code I just want to make sure that you understand exactly what I'm trying to achieve. I want to better understand the Maths thats going on within mainly the -(void)move:(id)sender
so I might be able to stop the UIImage/UIImageView from moving outside the UI subview (layoutOne) that I've created. If you might be able help me that would be really appreciated! Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我想出了如何用上面使用的方法来做到这一点。一旦我弄清楚我需要做什么,这真的很容易。如果您在上面使用此方法,您所需要做的就是确保您在本例中使用的
UIView
名为layoutOne
。在move:
、rotate:
、scale:
方法中需要添加layoutOne.clipsToBounds = YES;
确保它不在任何if
、else if
、else
语句内。这应该可以保证您想要交互的图像不会移动到 UIView 之外,相反,如果它触及视图的边界,则图像的那些部分将不会出现。简单!I figured out how to do this with the method I used above. It was really easy once I figured out what I needed to do. If your using this method above yourself, all you need to do is make sure the
UIView
your using in this case mine is calledlayoutOne
. In themove:
,rotate:
,scale:
methods you need to add inlayoutOne.clipsToBounds = YES;
making sure that it's not within any of theif
,else if
,else
statements. This should keep the image you wish to interact with doesn't move outside theUIView
instead if it touches the bounds of the View those parts of the image will not appear. Simples!