如何使用 GestureRecongnizers 阻止 UIImageView 在 UIView 之外移动?

发布于 2024-12-21 22:58:24 字数 5493 浏览 1 评论 0原文

我正在创建一个基于图像的应用程序,我希望显示的图像在我创建的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦境 2024-12-28 22:58:24

我想出了如何用上面使用的方法来做到这一点。一旦我弄清楚我需要做什么,这真的很容易。如果您在上面使用此方法,您所需要做的就是确保您在本例中使用的 UIView 名为 layoutOne。在 move:rotate:scale: 方法中需要添加 layoutOne.clipsToBounds = YES;确保它不在任何 ifelse ifelse 语句内。这应该可以保证您想要交互的图像不会移动到 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 called layoutOne. In the move:, rotate:, scale: methods you need to add in layoutOne.clipsToBounds = YES; making sure that it's not within any of the if, else if, else statements. This should keep the image you wish to interact with doesn't move outside the UIView instead if it touches the bounds of the View those parts of the image will not appear. Simples!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文