【问题标题】:Three Layers of Pan Gesture Recogniser Confusion平移手势识别器的三层混淆
【发布时间】:2013-05-21 14:47:46
【问题描述】:

在开发应用程序时,我遇到了平移手势识别器过多的问题。 我的第一个平移手势识别器位于 MainViewController 上,它是 RecipeSearchVC 的父级。这个手势识别器向左或向右滑动整个视图。 我在 RecipeSearchParametersVC 中的第二个平移手势识别器,它是页面视图控制器的父级。 第三个平移手势手势识别器被添加到嵌套在由 PageViewController 表示的视图控制器内的 UIControl Wheel。

我知道这听起来很疯狂,并且可以说这是糟糕的设计。但是,我相信这是凝聚力的工作,它会很好。

当试图旋转滚轮时,它会在手势被 PageViewController 或 MainViewController 超越之前旋转一两秒。通常是 MainViewController 接管。我可以采用哪些技术来清楚地区分这些手势识别器?

编辑:

在谈到平移手势识别器时,我的描述含糊不清,我深表歉意。 MainViewController 有它自己的 UIPanGestureRecpgniser 允许它向左或向右移动所有内容。 RecipeSearchParametersVC 只有一个 UIPanGestureRecogniser 因为它包含 UIPageViewController。它不添加手势识别器本身,而只是从 pageViewController 中获取它们。 UIControl 的手势识别器允许它跟踪它应该经历的旋转。

根据给出的建议,我可能会从页面视图控制器中删除手势并用按钮替换它们。我只是想让它像 iBooks 中的图像(可以滚动以显示更多图像)一样工作,所以我认为它可以正常工作。

UIControl UIPanGestureRecognser 代码

/**
 *  sent to the control when a touch related to the given event enters the control’s bounds
 *
 *  @param  touch                       uitouch object that represents a touch on the receiving control during tracking
 *  @param  event                       event object encapsulating the information specific to the user event
 */
- (BOOL)beginTrackingWithTouch:(UITouch *)touch
                     withEvent:(UIEvent *)event
{
    [super beginTrackingWithTouch:touch withEvent:event];

    CGPoint touchPoint                  = [touch locationInView:self];

    //  filter out touchs too close to centre of wheel
    CGFloat magnitudeFromCentre         = [self calculateDistanceFromCentre:touchPoint];

    if (magnitudeFromCentre < 40)       return NO;

    //  calculate distance from centre
    CGFloat deltaX                      = touchPoint.x - _container.center.x;
    CGFloat deltaY                      = touchPoint.y - _container.center.y;

    //  calculate the arctangent of the opposite (y axis) over the adjacent (x axis) to get the angle
    _deltaAngle                         = atan2(deltaY, deltaX);

    _startTransform                     = _container.transform;

    //  selection in limbo so set all sector image's to minimum value by changing current one
    [self getSectorByValue:_currentSector].alpha = kMinimumAlpha;

    return YES;
}

【问题讨论】:

  • 你能解决你的问题吗?

标签: iphone ios objective-c uigesturerecognizer uipageviewcontroller


【解决方案1】:

不幸的是,由于我的控制器层次结构的性质,我不得不重新考虑我的应用程序的设计。

带有 UIPanGestureRecogniser 的 MainViewController 保持原样。 带有 UIControl 的 UIPageViewController 已移至单独的静态视图控制器。

这效果要好得多,但还不理想。 UIPageViewController 窃取了任何水平平移,但是这可以通过实现按钮来替代滚动来解决。

UIControl 没有手势识别器,但我重写了 beginTrackingWithTouch: 和其他方法来跟踪触摸。

我想答案应该是:如果你叠加了太多手势,那你就错了。

【讨论】:

    【解决方案2】:

    你需要在轮子上添加一个容器,然后你可以做类似的事情,如果我没有遗漏什么,这段代码必须工作。

    UIPanGestureRecognizer* pan1 = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan1:)];
    [self.view addGestureRecognizer:pan1];
    UIPanGestureRecognizer* pan2 = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan2:)];
    [view2 addGestureRecognizer:pan2];
    UIPanGestureRecognizer* pan3 = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan3:)];
    [view3 addGestureRecognizer:pan3];
    
    - (void) pan1:(UIPanGestureRecognizer*)sender{
        NSLog(@"%@",sender);
    }
    
    - (void) pan2:(UIPanGestureRecognizer*)sender{
        NSLog(@"%@",sender);
    }
    
    - (void) pan3:(UIPanGestureRecognizer*)sender{
        NSLog(@"%@",sender);
    }
    

    【讨论】:

      【解决方案3】:

      我相信您会定义 3 个不同的 UIPanGesture 对象并将其附加到相应的视图中。

      虽然从技术上讲这是正确的,但它可能会引起一些混乱,例如,如果您有多个重叠的视图(这里有 3 个)并且需要将触摸发送到不在视图堆栈顶部的视图会发生什么?这个手势最终可能会令人困惑。

      相反,可以将单个手势识别器附加到多个目标视图的父视图,并根据用户触摸位置的坐标将手势委托给正确的视图。为此,您需要将源自任何子视图的触摸坐标标准化为定义 UIPanGesture 的父视图。这样你就可以知道平底锅在轮子上或其他地方发生的位置。

      PS:话虽如此,我强烈认为这是一个设计陷阱,它会伤害你。我做过这样的事情,但最终你会偶然发现一些用户交互会很糟糕的极端情况。如果这是您应用的主视图,我建议您重新考虑设计。

      【讨论】:

        【解决方案4】:

        我可以采用哪些技术来清楚地区分这些手势识别器?

        您应该查看UIGestureRecognizerDelegate 方法:

        - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer 
        

        询问代表是否应该允许两个手势识别器同时识别手势。

        当通过gestureRecognizer 或otherGestureRecognizer 识别手势会阻止其他手势识别器识别其手势时调用此方法。注意返回YES保证允许同时识别;另一方面,返回 NO 并不能保证防止同时识别,因为其他手势识别器的委托可能会返回 YES。

        我相信这将解决您的手势被其他手势“取代”的问题。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-04-20
          相关资源
          最近更新 更多