ios - UIPanGestureRecognizer 有时不会进入结束状态
问题描述
我正在开发像 Tinder 一样的卡片视图。当卡片 X 原点大于我声明的值时,它会移出屏幕。否则,它会再次居中。我在UIPanGestureRecognizer
函数内部做所有这些事情。我可以在Change
状态下移动视图。但是,它有时不会进入结束状态,因此卡片既不会移出屏幕,也不会再次停留在中心位置。它只是停留在某个奇怪的地方。
所以我的问题是卡片应该像下面的屏幕截图一样离开屏幕或粘在中间。
我在下面的帖子中尝试了解决方案,但没有任何效果:
UIPanGestureRecognizer 未调用结束状态
如果用户在负方向平移 x 和 y,UIPanGestureRecognizer 不会切换到状态“结束”或“取消”
/// 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
}
}
解决方案
我正在检查如果我在水平方向滑动:
let velocity = sender.velocity(in: self.view)
if abs(velocity.y) > abs(velocity.x) {
return
}
出于某种原因,当我水平滑动时,它正在返回。当我评论这段代码时,一切都开始工作了:)
推荐阅读
- android - Firestore 查询侦听器可以“侦听”云功能吗?
- node.js - 状态活动中的 discord.js 自动角色
- javascript - 对访问 null 的 next 属性感到困惑?
- netbeans - 我在 netbeans ide 中的 derby 连接出现错误
- python - 在Python中从带有非字母数字字符的字符串中获取文本
- python - Mongo复杂多条件字段标准化
- php - 我想查看我的页面,但它一直说未定义的变量:$jobs
- go - 如何在 Wayland 的 Gtk3 窗口中嵌入 libvlc 播放器
- c# - Visual Studio 2019 发布项目不起作用
- javascript - 如何在图片中的特定点添加css动画