【问题标题】:UIPanGestureRecognizer sometimes doesn't get into End StateUIPanGestureRecognizer 有时不会进入结束状态
【发布时间】:2018-09-21 08:34:36
【问题描述】:

我正在开发类似 Tinder 中的卡片视图。当卡片 X 原点大于我声明的值时,它会移出屏幕。否则,它会再次居中。我在UIPanGestureRecognizer 函数中做所有这些事情。我可以在Change 状态下移动视图。但是,它有时不会进入结束状态,因此卡片既不会移出屏幕,也不会再次停留在中心位置。它只是停留在某个奇怪的地方。

所以我的问题是卡片应该像下面的屏幕截图一样离开屏幕或粘在中间。

我在下面的帖子中尝试了解决方案,但没有任何效果:

UIPanGestureRecognizer not calling End state

UIPanGestureRecognizer does not switch to state "End" or "Cancel" if user panned x and y in negative direction

/// This method handles the swiping gesture on each card and shows the appropriate emoji based on the card's center.
@objc func handleCardPan(sender: UIPanGestureRecognizer) {

    // Ensure it's a horizontal drag
    let velocity = sender.velocity(in: self.view)
    if abs(velocity.y) > abs(velocity.x) {
        return
    }

    // if we're in the process of hiding a card, don't let the user interace with the cards yet
    if cardIsHiding { return }
    // change this to your discretion - it represents how far the user must pan up or down to change the option
    // distance user must pan right or left to trigger an option
    let requiredOffsetFromCenter: CGFloat = 80

    let panLocationInView = sender.location(in: view)
    let panLocationInCard = sender.location(in: cards[0])

    switch sender.state {
    case .began:
        dynamicAnimator.removeAllBehaviors()
        let offset = UIOffsetMake(cards[0].bounds.midX, panLocationInCard.y)
        // card is attached to center
        cardAttachmentBehavior = UIAttachmentBehavior(item: cards[0], offsetFromCenter: offset, attachedToAnchor: panLocationInView)
        //dynamicAnimator.addBehavior(cardAttachmentBehavior)
        let translation = sender.translation(in: self.view)
        print(sender.view!.center.x)
        sender.view!.center = CGPoint(x: sender.view!.center.x + translation.x, y: sender.view!.center.y)

        sender.setTranslation(CGPoint(x: 0, y: 0), in: self.view)
    case .changed:
        //cardAttachmentBehavior.anchorPoint = panLocationInView
        let translation = sender.translation(in: self.view)
        print(sender.view!.center.x)
        sender.view!.center = CGPoint(x: sender.view!.center.x + translation.x, y: sender.view!.center.y)
        sender.setTranslation(CGPoint(x: 0, y: 0), in: self.view)

    case .ended:

        dynamicAnimator.removeAllBehaviors()

        if !(cards[0].center.x > (self.view.center.x + requiredOffsetFromCenter) || cards[0].center.x < (self.view.center.x - requiredOffsetFromCenter)) {
            // snap to center
            let snapBehavior = UISnapBehavior(item: cards[0], snapTo: CGPoint(x: self.view.frame.midX, y: self.view.frame.midY + 23))
            dynamicAnimator.addBehavior(snapBehavior)
        } else {
            let velocity = sender.velocity(in: self.view)
            let pushBehavior = UIPushBehavior(items: [cards[0]], mode: .instantaneous)
            pushBehavior.pushDirection = CGVector(dx: velocity.x/10, dy: velocity.y/10)
            pushBehavior.magnitude = 175
            dynamicAnimator.addBehavior(pushBehavior)

            // spin after throwing
            var angular = CGFloat.pi / 2 // angular velocity of spin
            let currentAngle: Double = atan2(Double(cards[0].transform.b), Double(cards[0].transform.a))

            if currentAngle > 0 {
                angular = angular * 1
            } else {
                angular = angular * -1
            }
            let itemBehavior = UIDynamicItemBehavior(items: [cards[0]])
            itemBehavior.friction = 0.2
            itemBehavior.allowsRotation = true
            itemBehavior.addAngularVelocity(CGFloat(angular), for: cards[0])
            dynamicAnimator.addBehavior(itemBehavior)

            showNextCard()
            hideFrontCard()

        }
    default:
        break
    }
}

【问题讨论】:

  • 您尚未检查canceledfailed 状态。对于调试,添加这些状态,如果您遇到其中任何一种,您仍然可以根据最后一次触摸位置执行您的 move 代码,或者调查手势失败/被取消的原因。

标签: ios swift uipangesturerecognizer


【解决方案1】:

我正在检查是否水平滑动:

let velocity = sender.velocity(in: self.view)
if abs(velocity.y) > abs(velocity.x) {
    return
}

由于某种原因,当我水平滑动时,它正在返回。当我评论这段代码时,一切都开始工作了:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-11
    • 1970-01-01
    • 2015-12-23
    • 2011-05-26
    • 1970-01-01
    • 2019-05-24
    • 1970-01-01
    相关资源
    最近更新 更多