swift - UIScreenEdgeRecognizerGesture 像 safari 一样流畅

标签 swift animation uigesturerecognizer

我的容器 View Controller 有一个屏幕边缘平移手势来改变 View 。平移 View 的代码如下所示:

func changeView(recognizer: UIScreenEdgePanGestureRecognizer) {

    println("INITIAL: \(recognizer.translationInView(view))")

    if recognizer.state == .Began {
        // Create and configure the view

        println("BEGAN: \(recognizer.translationInView(view))")
    }

    if recognizer.state == .Changed {
        println("CHANGED: \(recognizer.translationInView(view))")

        let translation = recognizer.translationInView(view)

        currentView.view.center.x += translation.x
        pendingView.view.center.x += translation.x

        recognizer.setTranslation(CGPointZero, inView: view)
    }

    if recognizer.state == .Ended {
        if recognizer.view!.center.x > view.bounds.size.width {
            // Animate the view to position
        } else {
            // Animate the view back to original
        }
    }
}

虽然这有效,但我仍然对平移的开始有疑问。当用户快速滑动时,translation 的值会大到足以让平移的开始看起来“不流畅”。

例如,快速滑动 translation 将从 100 开始。然后将该值添加到导致不良影响的 View 的 center.x

我注意到 Safari 也有一个屏幕边缘手势来改变 View ,无论滑动多快都不会出现这种效果。普通的 UIPanGestureRecognizer 也不会发生这种情况。

我试过在 UIView.animateWithDuration() 中包装“动画”。它确实看起来更流畅,但感觉它只是滞后于实际手势,这与在 Safari 中的表现不同。

谁能告诉我一种更好的平移 View 的方法,使其看起来像在 Safari 中一样流畅?

编辑:
我已经添加了几行来检查翻译的值,问题是它从 0 跳到某个值导致不需要的行为。我把 recognizer.setTranslation(CGPointZero, inView: view) 放在哪里并不重要。

输出是:

INITIAL: (21.5, 0.0)
BEGAN:   (21.5, 0.0)
INITIAL: (188.0, -3.0)
CHANGED: (188.0, -3.0)

经过更多测试:

func changeView(recognizer: UIScreenEdgePanGestureRecognizer) {
    println("INITIAL: \(recognizer.translationInView(view))")
    recognizer.setTranslation(CGPointZero, inView: view)
}

INITIAL: (0.0, 0.0)
INITIAL: (130.5, -35.5)

最终:
似乎创建和准备新 View 在 Began 中造成了某种轻微的滞后。少量的滞后足以造成 100-200 的翻译差异。

我想可能必须在其他地方预加载 View 。

最佳答案

这不会解决您所有的问题,因为正如您所说的那样,屏幕边缘平移手势识别器的行为有点粗鲁;但请注意,您遗漏了一个有值(value)的数据 - recognizer.translationInView 是什么.Began 状态 的问题。那个时候,显然,手指已经移动了很多;因为,如果没有,我们就不会将其识别为屏幕边缘平移手势!因此,我认为,如果您像这样构建测试,您会更快乐:

    switch recognizer.state {
    case .Began:
        // ... do initial setup
        fallthrough // <-- TAKE NOTE
    case .Changed:
        // respond to changes
    default:break
    }

这样一来,你就会捕捉到缺失的数据并做出响应,跳转就不会那么糟糕了。

我尝试登录 beganchanged 以及我的号码(显示 translationInViewno setTranslation 回零)是这样的事情:

began
changed
(-16.5, 0.0)
changed
(-41.5, 0.0)
changed
(-41.5, 0.0)
changed
(-58.5, 0.0)

(第一个,在 began 之前,是 changedfallthrough 执行。)所以是的,我们确实从无到有-41 非常快,但至少有一个中间值 -16.5,所以它不是那么突然。

另外我要补充一点,如果有严重的延迟和跳跃,很可能是你有多个相互冲突的手势识别器。如果是这样,您可以通过使用诸如 gestureRecognizer:shouldRequireFailureOfGestureRecognizer: 之类的委托(delegate)方法来检测这一事实 - 这也可以让您在它们之间确定优先级,并可能使其他 g.r.早点让路。

关于swift - UIScreenEdgeRecognizerGesture 像 safari 一样流畅,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30277916/

相关文章:

swift - 并行添加到数组

ios - iPhone X 键盘出现显示额外的空间

java - 如何在java gui中创建动画矩形?

javascript - 如何在 Jquery 中切换动画

ios - 尝试在手势识别时翻转单元格上的 ImageView ,代码工作正常但没有翻转

ios - TouchBegan 在 iOS 12 中被调用,但在 iOS 13 中未被调用

ios - iOS 应用程序中的 Realm 文件大小

ios - NumberFormatter 字符串作为次要货币单位而不是区域设置的主要单位(例如 99p 不是 £0.99)

ios - 使用父 View 的框架更改调整 subview 的大小

ios - 在另一个类中滑动手势识别器