繁体   English   中英

泛手势-滑动手势冲突

[英]Pan Gesture - Swipe Gesture Conflict

我正在尝试创建一个应用程序,该应用程序可以复制Apple的照片应用程序(iPhone)缩放,平移和滚动照片图像的功能。 (在查看pdf和其他文档时,我也想使用相同的控件。)我得到了点击手势来显示/隐藏导航栏,并且获得了滑动手势来从左向右滚动图像,反之亦然。 然后,我得到了放大和缩小的捏合手势,但是当我添加平移手势以在缩放的图像中四处移动时,滑动手势就停止了工作。

我在StackOverflow的其他地方找到了可能的解决方案,包括使用shouldRecognizeSimultaneouslyWithGestureRecognizer ,但是到目前为止,我还无法解决冲突。 有什么建议么?

这是代码:

func gestureRecognizer(UIPanGestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer UISwipeGestureRecognizer: UIGestureRecognizer) -> Bool {
    return true
}

@IBAction func handlePinch(sender: UIPinchGestureRecognizer) {

    sender.view!.transform = CGAffineTransformScale(sender.view!.transform, sender.scale, sender.scale)
    sender.scale = 1
}

@IBAction func handlePan(sender: UIPanGestureRecognizer) {

    self.view.bringSubviewToFront(sender.view!)
    var translation = sender.translationInView(self.view)
    sender.view!.center = CGPointMake(sender.view!.center.x + translation.x, sender.view!.center.y + translation.y)
    sender.setTranslation(CGPointZero, inView: self.view)
}

@IBAction func handleSwipeRight(sender: UISwipeGestureRecognizer) {

    if (self.index == 0) {
    self.index = ((photos.count) - 1);
    }
    else
    {
    self.index--;
    }

    // requireGestureRecognizerToFail(panGesture)

    setImage()
}

您不希望shouldRecognizeSimultaneouslyWithGestureRecognizer:允许两个手势同时发生)。 例如,如果要同时捏和平移,这很有用。 但是,在您同时摇动和滑动的情况下,同时手势将无济于事。 (如果有的话,同时识别它们可能会使情况混乱。)

相反,您可能想使用requireGestureRecognizerToFail:建立滑动和平移手势的优先级(例如,只有在滑动失败时才平移)。

或更妙的是,完全撤消滑动手势,而仅使用平移手势,如果将其缩小,则将是一种交互式手势,可以从一个图像导航到下一个图像,如果放大,则可以平移图像。 无论如何,交互式平移手势通常会更令人满意。 例如,如果从一张照片滑动到另一张照片,则可以停止平移手势并返回。 如果查看Photos.app,它实际上是使用平移手势从一个图像滑动到另一图像,而不是滑动手势。

我在http://www.raywenderlich.com/76436/use-uiscrollview-scroll-zoom-content-swift上找到了一个教程,该教程很好地介绍了UIScrollView,它是Swift中缩放,平移和分页的一种组合方式。 我建议所有尝试学习如何使这些手势一起正常工作的人使用它。

在类似情况下,我使用了另一种方法:扩展了平移手势以支持滑动:

 // in handlePan()
switch recognizer.state {


 struct Holder {
                static var lastTranslate : CGFloat = 0
                static var prevTranslate : CGFloat = 0
                static var lastTime : TimeInterval = 0
                static var prevTime : TimeInterval = 0
            }

        case .began:

            Holder.lastTime = Date.timeIntervalSinceReferenceDate
            Holder.lastTranslate = translation.y
            Holder.prevTime = Holder.lastTime
            Holder.prevTranslate = Holder.lastTranslate


            //perform appropriate pan action

        case .changed:

            Holder.prevTime = Holder.lastTime
            Holder.prevTranslate = Holder.lastTranslate
            Holder.lastTime = Date.timeIntervalSinceReferenceDate
            Holder.lastTranslate = translation.y

            //perform appropriate pan action

        case .ended ,.cancelled:

            let seconds = CGFloat(Date.timeIntervalSinceReferenceDate) - CGFloat(Holder.prevTime)
            var swipeVelocity : CGFloat = 0
            if seconds > 0 {
                swipeVelocity = (translation.y - Holder.prevTranslate)/seconds
            }

            var shouldSwipe : Bool = false
            if Swift.abs(swipeVelocity) > velocityThreshold {
                shouldSwipe = swipeVelocity < 0
            }
            if shouldSwipe {
               // perform swipe action
            } else {
                // perform appropriate pan action
            }

        default:
            print("Unsupported")
        }

您所需要做的就是为您的滑动手势找到合适的velocityTreshold

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM