是否有可以同时捏住和平移手势的手势识别器? [英] Is there a gesture recognizer that handles both pinch and pan together?

查看:68
本文介绍了是否有可以同时捏住和平移手势的手势识别器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我正在使用iOS 4.2向我的应用程序添加缩放和平移.我已经实现了UIPinchGestureRecognizer和UIPanGestureRecognizer的实例.在我看来,其中只有一个可以一次识别手势.特别地,后者仅在一个手指向下时做出反应,而前者在第二根手指出现时做出反应.没关系,但是我认为这会带来一些劣质的用户体验.

So I am working with the iOS 4.2 to add zoom and pan to my application. I have implemented an instance of the UIPinchGestureRecognizer and UIPanGestureRecognizer. It seems to me that only one of these is recognizing a gesture at a time. In particular, the latter only reacts when one finger is down, while the former reacts when the second finger is present. That is okay, but it has some side effects that I think make for inferior quality of user experience.

当您放下两个手指,然后移动其中一根手指时,图像会像应有的那样扩展(放大),但是手指下方的像素不再位于手指下方.图像从图像中心缩放,而不是从两个手指之间的中点缩放.那个中心点本身在移动.我希望该中心点的移动决定整个图像的平移.

When you put two fingers down and then move one of them, the image expands (zooms in) like it should, but the pixels under the fingers are no longer under the finger. The image scales from the center of the image, not the mid point between the two fingers. And that center point is itself moving. I want that center point's movement to dictate the panning of the image overall.

几乎所有的iOS应用程序都具有相同的行为,即图像在图像中心附近放大或缩小,而不是手指下方的像素跟踪手指吗?

Do nearly all iOS applications have this same behavior, where the image zooms in or out around the center of the image rather than the pixels under the fingers tracking the fingers?

在我看来,创建自定义手势识别器是解决此问题的正确设计方法,但在我看来,有人会为商业免费下载和使用而创建这样的识别器.是否有这样的UIGestureRecognizer?

It seems to me that creating a custom gesture recognizer is the correct design approach to this problem, but it also seems to me that someone would have created such a recognizer for commercially free download and use. Is there such a UIGestureRecognizer?

推荐答案

因此,我创建了自定义手势识别器,没有人给我一个更好的解决方案,从而获得了所需的结果.以下是一些关键代码片段,可让自定义识别器以质心作为平移和缩放效果的中心来指示视图应在何处重新定位以及其新缩放比例应如何,以便手指下的像素完全保留在手指下时间,除非手指似乎旋转,否则这是不被支持的,并且我无法采取任何措施阻止这种手势.此手势识别器可以用两个手指同时平移和缩放.以后,即使抬起两根手指中的一根,我也需要为一根手指的平移添加支持.

So I created the custom gesture recognizer in light of no one giving me a better solution that achieved the desired results. Below are the key code fragments that allow the custom recognizer to indicate where the view should reposition and what its new scale should be with the centroid as the center of the pan and zoom effects so that the pixels under the fingers remain under the fingers at all time, unless the fingers appear to rotate, which is not supported and I can't do anything to stop them from such a gesture. This gesture recognizer pans and zooms simultaneously with two fingers. I need to add support later for one finger panning, even when one of two fingers is lifted up.

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    // We can only process if we have two fingers down...
    if ( FirstFinger == nil || SecondFinger == nil )
        return;

    // We do not attempt to determine if the first finger, second finger, or
    // both fingers are the reason for this method call. For this reason, we
    // do not know if either is stale or updated, and thus we cannot rely
    // upon the UITouch's previousLocationInView method. Therefore, we need to
    // cache the latest UITouch's locationInView information each pass.

    // Break down the previous finger coordinates...
    float A0x = PreviousFirstFinger.x;
    float A0y = PreviousFirstFinger.y;
    float A1x = PreviousSecondFinger.x;
    float A1y = PreviousSecondFinger.y;
    // Update our cache with the current fingers for next pass through here...
    PreviousFirstFinger = [FirstFinger locationInView:nil];
    PreviousSecondFinger = [SecondFinger locationInView:nil];
    // Break down the current finger coordinates...
    float B0x = PreviousFirstFinger.x;
    float B0y = PreviousFirstFinger.y;
    float B1x = PreviousSecondFinger.x;
    float B1y = PreviousSecondFinger.y;


    // Calculate the zoom resulting from the two fingers moving toward or away from each other...
    float OldScale = Scale;
    Scale *= sqrt((B0x-B1x)*(B0x-B1x) + (B0y-B1y)*(B0y-B1y))/sqrt((A0x-A1x)*(A0x-A1x) + (A0y-A1y)*(A0y-A1y));

    // Calculate the old and new centroids so that we can compare the centroid's movement...
    CGPoint OldCentroid = { (A0x + A1x)/2, (A0y + A1y)/2 };
    CGPoint NewCentroid = { (B0x + B1x)/2, (B0y + B1y)/2 };    

    // Calculate the pan values to apply to the view so that the combination of zoom and pan
    // appear to apply to the centroid rather than the center of the view...
    Center.x = NewCentroid.x + (Scale/OldScale)*(self.view.center.x - OldCentroid.x);
    Center.y = NewCentroid.y + (Scale/OldScale)*(self.view.center.y - OldCentroid.y);
}

视图控制器通过为相关视图分配新的比例尺和中心来处理事件.我注意到其他手势识别器倾向于允许控制器执行一些数学运算,但是我尝试在识别器中执行所有数学运算.

The view controller handles the events by assigning the new scale and center to the view in question. I noticed that other gesture recognizers tend to allow the controller to do some of the math, but I tried to do all the math in the recognizer.

-(void)handlePixelTrack:(PixelTrackGestureRecognizer*)sender
{
    sender.view.center= sender.Center;
    sender.view.transform = CGAffineTransformMakeScale(sender.Scale, sender.Scale);
}

这篇关于是否有可以同时捏住和平移手势的手势识别器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆