沿 Y 轴的 UIView 平移手势
UIView pan gesture along Y axis
我有一个 UIView,我可以沿着 Y 轴拖放它,然后捕捉到 2 个位置中的 1 个。问题是我必须将它拖到 Y 轴上的某个点上才能使其卡入到位。当您尝试快速滑动但没有超过特定的 Y 轴时,这感觉很笨拙,它会快速回到起始位置。
我想要的目标是根据用户在释放 UIView 时滑动的方向,使其捕捉到 2 个位置中的 1 个位置。
@objc func panGesture(recognizer: UIPanGestureRecognizer) {
let window = UIApplication.shared.keyWindow
let translation = recognizer.translation(in: self)
let currentY = self.frame.minY
let partialY = (window?.frame.height)!-194
let halfWayPoint = ((window?.frame.height)!/2)-40
self.frame = CGRect(x: 0, y: currentY + translation.y, width: self.frame.width, height: self.frame.height)
recognizer.setTranslation(CGPoint.zero, in: self)
switch recognizer.state {
case .changed:
// Prevent scrolling up past y:0
if currentY <= 0
{
self.frame = CGRect(x: 0, y: 0, width: self.frame.width, height: self.frame.height)
}
case .ended:
// Snap to 80 (y) (expanded)
if currentY < 80 || currentY > 80 && currentY < halfWayPoint
{
UIView.animate(withDuration:0.62, delay: 0.0, usingSpringWithDamping: 0.62, initialSpringVelocity: 0.5, options: .curveEaseInOut, animations:
{
recognizer.view!.frame = CGRect(x: 0, y: 80, width: self.frame.width, height: self.frame.height)
}, completion: { (true) in
self.isExpanded = true
})
}
// Snap back to partial (y) (original position)
if currentY > partialY || currentY < partialY && currentY > halfWayPoint
{
UIView.animate(withDuration:0.62, delay: 0.0, usingSpringWithDamping: 0.62, initialSpringVelocity: 0.5, options: .curveEaseInOut, animations:
{
recognizer.view!.frame = CGRect(x: 0, y: partialY, width: self.frame.width, height: self.frame.height)
}, completion: {(true) in
self.isExpanded = false
})
}
default:
print("Default")
}
如您所见,halfWayPoint 是视图必须位于上方或下方的点,以确定它捕捉到的位置。这是无效的,我想根据用户拖动视图的方向(向上或向下)来执行此操作。
我建议您使用 UIPanGestureRecognizers velicoty(in:) 方法。
它为您提供滑动速度(以点/秒为单位)。
如果你只是将它添加到 currentY
(最好用一些常数缩放),你会得到那种轻弹的感觉,并且手势会感觉更自然。
只是更换
let currentY = self.frame.minY
和 let currentY = self.frame.minY + recognizer.velocity(in: nil).y * someConstant
一起玩 someConstant
直到你得到你想要的感觉。
我有一个 UIView,我可以沿着 Y 轴拖放它,然后捕捉到 2 个位置中的 1 个。问题是我必须将它拖到 Y 轴上的某个点上才能使其卡入到位。当您尝试快速滑动但没有超过特定的 Y 轴时,这感觉很笨拙,它会快速回到起始位置。
我想要的目标是根据用户在释放 UIView 时滑动的方向,使其捕捉到 2 个位置中的 1 个位置。
@objc func panGesture(recognizer: UIPanGestureRecognizer) {
let window = UIApplication.shared.keyWindow
let translation = recognizer.translation(in: self)
let currentY = self.frame.minY
let partialY = (window?.frame.height)!-194
let halfWayPoint = ((window?.frame.height)!/2)-40
self.frame = CGRect(x: 0, y: currentY + translation.y, width: self.frame.width, height: self.frame.height)
recognizer.setTranslation(CGPoint.zero, in: self)
switch recognizer.state {
case .changed:
// Prevent scrolling up past y:0
if currentY <= 0
{
self.frame = CGRect(x: 0, y: 0, width: self.frame.width, height: self.frame.height)
}
case .ended:
// Snap to 80 (y) (expanded)
if currentY < 80 || currentY > 80 && currentY < halfWayPoint
{
UIView.animate(withDuration:0.62, delay: 0.0, usingSpringWithDamping: 0.62, initialSpringVelocity: 0.5, options: .curveEaseInOut, animations:
{
recognizer.view!.frame = CGRect(x: 0, y: 80, width: self.frame.width, height: self.frame.height)
}, completion: { (true) in
self.isExpanded = true
})
}
// Snap back to partial (y) (original position)
if currentY > partialY || currentY < partialY && currentY > halfWayPoint
{
UIView.animate(withDuration:0.62, delay: 0.0, usingSpringWithDamping: 0.62, initialSpringVelocity: 0.5, options: .curveEaseInOut, animations:
{
recognizer.view!.frame = CGRect(x: 0, y: partialY, width: self.frame.width, height: self.frame.height)
}, completion: {(true) in
self.isExpanded = false
})
}
default:
print("Default")
}
如您所见,halfWayPoint 是视图必须位于上方或下方的点,以确定它捕捉到的位置。这是无效的,我想根据用户拖动视图的方向(向上或向下)来执行此操作。
我建议您使用 UIPanGestureRecognizers velicoty(in:) 方法。 它为您提供滑动速度(以点/秒为单位)。
如果你只是将它添加到 currentY
(最好用一些常数缩放),你会得到那种轻弹的感觉,并且手势会感觉更自然。
只是更换
let currentY = self.frame.minY
和 let currentY = self.frame.minY + recognizer.velocity(in: nil).y * someConstant
一起玩 someConstant
直到你得到你想要的感觉。