Ограничение UIAttachmentBehavior для ответа по горизонтали только в Swift 4

У меня есть вид карты, как показано на рисунке ниже. Работает как в Tinder. Когда пользователь смахивает карту, она переходит в фоновый режим, а новая выходит на передний план. Теперь он может быть проведен во всех направлениях. Однако я хочу, чтобы эта карта двигалась только влево или вправо без какого-либо угла. Поэтому я хочу, чтобы UIAttachmentBehaviour работал только для левых и правых жестов, а также ограничивал изменение положения карт только в направлении X, а не в Y.

/// UIKit dynamics variables that we need references to.
var dynamicAnimator: UIDynamicAnimator!
var cardAttachmentBehavior: UIAttachmentBehavior!

@objc func handleCardPan(sender: UIPanGestureRecognizer) {
    // 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
    let optionLength: CGFloat = 60
    // distance user must pan right or left to trigger an option
    let requiredOffsetFromCenter: CGFloat = 15

    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 - cards[0].bounds.midY)
        // card is attached to center
        cardAttachmentBehavior = UIAttachmentBehavior(item: cards[0], offsetFromCenter: offset, attachedToAnchor: panLocationInView)
        dynamicAnimator.addBehavior(cardAttachmentBehavior)
    case .changed:
        cardAttachmentBehavior.anchorPoint = panLocationInView
    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: self.view.center)
                            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
    }
}

0 ответов

Другие вопросы по тегам