如何获得VC中向上/向下的滚动/滑动方向?
我想在我的VC中添加一个UIScrollView或其他内容,以查看用户是否向上/向下滑动/滚动,然后根据其是向上/向下手势来隐藏/显示UIView
。
如果使用UIScrollView
,则可以从scrollViewDidScroll:
功能中受益。您需要保存它的最后一个位置(scrollViewDidScroll:
)并按照以下方式进行更新:
contentOffset
当然还有其他方法可以做到这一点。
希望对您有帮助。
声明这些func scrollViewDidScroll(_ scrollView: UIScrollView) {
switch checkScrollDirection(scrollView) {
case .up:
// move up
case .down:
// move down
default:
break
}
lastContentOffset = scrollView.contentOffset
}
和enum
。
protocol
来自enum ScrollDirection { case up, left, down, right, none } protocol ScrollDirectionDetectable { associatedtype ScrollViewType: UIScrollView var scrollView: ScrollViewType { get } var scrollDirection: ScrollDirection { get set } var lastContentOffset: CGPoint { get set } } extension ScrollDirectionDetectable { var scrollView: ScrollViewType { return self.scrollView } }
的使用
ViewController
如果要使用特定的方向,只需更新所需的特定// Set ScrollDirectionDetectable which has UIScrollViewDelegate
class YourViewController: UIViewController, ScrollDirectionDetectable {
// any types that inherit UIScrollView can be ScrollViewType
typealias ScrollViewType = UIScrollView
var lastContentOffset: CGPoint = .zero
var scrollDirection: ScrollDirection = .none
}
extension YourViewController {
func scrollViewDidScroll(_ scrollView: UIScrollView) {
// Update ScrollView direction
if self.lastContentOffset.x > scrollView.contentOffset.x {
scrollDirection = .left
} else if self.lastContentOffset.x > scrollView.contentOffset.x {
scrollDirection = .right
}
if self.lastContentOffset.y > scrollView.contentOffset.y {
scrollDirection = .up
} else if self.lastContentOffset.y < scrollView.contentOffset.y {
scrollDirection = .down
}
self.lastContentOffset.x = scrollView.contentOffset.x
self.lastContentOffset.y = scrollView.contentOffset.y
}
}
。
view controller:
contentOffset
维克多的答案很好,但价格昂贵,因为您一直在比较和存储值。如果您的目标是无需昂贵的计算即可立即确定滚动方向,请尝试使用此[[using Swift:
// variable to save the last position visited, default to zero
private var lastContentOffset: CGFloat = 0
func scrollViewDidScroll(scrollView: UIScrollView!) {
if (self.lastContentOffset > scrollView.contentOffset.y) {
// move up
}
else if (self.lastContentOffset < scrollView.contentOffset.y) {
// move down
}
// update the new position acquired
self.lastContentOffset = scrollView.contentOffset.y
}
然后你去。同样,如果您需要不断跟踪,请使用Victors答案,否则我更喜欢这种解决方案。 😊
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
let translation = scrollView.panGestureRecognizer.translation(in: scrollView.superview)
if translation.y > 0 {
// swipes from top to bottom of screen -> down
} else {
// swipes from bottom to top of screen -> up
}
}
,然后将scrollView.contentSize.height - scrollView.frame.height
范围限制为大于0或小于scrollView.contentOffset.y
,我添加了约束,弹回时不会进行任何更改。scrollView.contentSize.height - scrollView.frame.height
对于swift4
实现func scrollViewDidScroll(_ scrollView: UIScrollView) {
if lastContentOffset > scrollView.contentOffset.y && lastContentOffset < scrollView.contentSize.height - scrollView.frame.height {
// move up
} else if lastContentOffset < scrollView.contentOffset.y && scrollView.contentOffset.y > 0 {
// move down
}
// update the new position acquired
lastContentOffset = scrollView.contentOffset.y
}
方法,该方法可检测到您平移手势的y轴超出0:]scrollViewDidScroll
启用了跳动的tableView解决方案。因此,我只使用了部分解决方案以及一些历史悠久的经典布尔标志解决方案。
1)因此,首先,您可以为scrollDirection使用一个枚举:public func scrollViewDidScroll(_ scrollView: UIScrollView) {
if(scrollView.panGestureRecognizer.translation(in: scrollView.superview).y > 0) {
print("up")
}
else {
print("down")
}
}
2)设置3个新的私有变量,以帮助我们存储lastOffset,scrollDirection和一个用于启用/禁用滚动方向计算的标志(帮助我们忽略tableView的反弹效果),您稍后将使用它:
enum ScrollDirection { case up, down }
3)在scrollViewDidScroll中添加以下内容:
private var shouldCalculateScrollDirection = false private var lastContentOffset: CGFloat = 0 private var scrollDirection: ScrollDirection = .up
4)如果尚未实现scrollViewDidEndDragging,请实施并在其中添加以下代码行:
func scrollViewDidScroll(_ scrollView: UIScrollView) { // The current offset let offset = scrollView.contentOffset.y // Determine the scolling direction if lastContentOffset > offset && shouldCalculateScrollDirection { scrollDirection = .down } else if lastContentOffset < offset && shouldCalculateScrollDirection { scrollDirection = .up } // This needs to be in the last line lastContentOffset = offset }
5)如果尚未实现scrollViewWillBeginDecelerating,请实现它并在其中添加以下代码行:
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) { guard !decelerate else { return } shouldCalculateScrollDirection = false }
6)最后,如果尚未实现scrollViewWillBeginDragging,请实现它,并在其中添加以下代码行:
func scrollViewWillBeginDecelerating(_ scrollView: UIScrollView) { shouldCalculateScrollDirection = false }
如果您按照上述所有步骤操作,那就太好了!您可以去任何要使用此方向的地方,只需写:
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) { shouldCalculateScrollDirection = true }
switch scrollDirection {
case .up:
// Do something for scollDirection up
case .down:
// Do something for scollDirection down
}
但是如果速度为0,则无法使用-在这种情况下,您别无选择,只能使用接受的答案的存储属性解决方案。
override func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
switch velocity {
case _ where velocity.y < 0:
// swipes from top to bottom of screen -> down
trackingDirection = .down
case _ where velocity.y > 0:
// swipes from bottom to top of screen -> up
trackingDirection = .up
default: trackingDirection = .none
}
}
,它将识别滑动到请求的方向(这将适用于所有视图,而不仅适用于UISwipeGestureRecognizer
UIScrollView
For Swift我认为最简单,最强大的方法是执行以下操作。它允许您跟踪方向更改的时间,并且仅在更改方向时做出反应。另外,如果需要在其他任何阶段在代码中进行查询,则始终可以访问class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let upGs = UISwipeGestureRecognizer(target: self, action: #selector(ViewController.handleSwipes(sender:)))
let downGs = UISwipeGestureRecognizer(target: self, action: #selector(ViewController.handleSwipes(sender:)))
upGs.direction = .up
downGs.direction = .down
self.view.addGestureRecognizer(upGs)
self.view.addGestureRecognizer(downGs)
}
@objc func handleSwipes(sender:UISwipeGestureRecognizer) {
if (sender.direction == .up) {
print("Up")
}
if (sender.direction == .down) {
print("Down")
}
}
}
滚动属性。
.lastDirection
以上假设您仅跟踪上/下滚动。可通过枚举自定义。您可以添加或更改enum WMScrollDirection { case Up, Down, None } class WMScrollView: UIScrollView { var lastDirection: WMScrollDirection = .None { didSet { if oldValue != lastDirection { // direction has changed, call your func here } } } override var contentOffset: CGPoint { willSet { if contentOffset.y > newValue.y { lastDirection = .Down } else { lastDirection = .Up } } } }
和.left
以跟踪任何方向。我希望这对某人有帮助。
欢呼声
.right
和scrollViewDelegate:
fileprivate var lastContentOffset: CGPoint = .zero func checkScrollDirection(_ scrollView: UIScrollView) -> UIScrollViewDirection { return lastContentOffset.y > scrollView.contentOffset.y ? .up : .down }