代码之家  ›  专栏  ›  技术社区  ›  Emre Önder

UIPangestureRecognitizer有时无法进入结束状态

  •  0
  • Emre Önder  · 技术社区  · 6 年前

    我正在开发一个卡片视图,就像在Tinder中一样。当cards X origin大于我声明的值时,它会移出屏幕。否则,它又会粘在中心。我在里面做这些事 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
        }
    }
    

    image

    1 回复  |  直到 6 年前
        1
  •  0
  •   Emre Önder    6 年前

    我在检查我是否在水平方向滑动:

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

    不知为什么,它是在我横扫的时候回来的。当我评论这段代码时,一切都开始工作了:)