如何在Swift中获得UIScrollView的垂直方向?

如何在VC中上下滚动/滑动方向?

我想在我的VC中添加一个UIScrollView或其他东西,可以看到用户滑动/向上或向下滑动,然后隐藏/显示一个UIView这取决于它是一个向上/向下的手势。

如果您使用UIScrollView那么您可以从scrollViewDidScroll:函数中获益。 你需要保存最后一个位置( contentOffset )和它的更新,如下所示:

 // 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 } 

还有其他的方法,当然这是他们的一个。

我希望这可以帮助你。

维克托的答案很好,但价格相当昂贵,因为你总是比较和存储价值。 如果您的目标是即时识别滚动方向而不需要昂贵的计算,那么使用Swift来试试这个:

 func scrollViewWillBeginDragging(scrollView: UIScrollView) { let translation = scrollView.panGestureRecognizer.translationInView(scrollView.superview!) if translation.y > 0 { // swipes from top to bottom of screen -> down } else { // swipes from bottom to top of screen -> up } } 

你去了。 同样,如果你需要不断跟踪,使用Victors回答,否则我更喜欢这个解决scheme。 😊

当滚动到滚动结束或滚动开始时,我用Victor的回答稍作改进,然后得到反弹效果。 我添加约束通过计算(scrollView.contentSize.height – scrollView.frame.height),然后限制scrollView.contentOffset.y范围大于0或小于(scrollView.contentSize.height – scrollView.frame.height) ,反弹时不会有变化。

  //code if(self.lastContentOffset > scrollView.contentOffset.y) && self.lastContentOffset < (scrollView.contentSize.height - scrollView.frame.height) { // move up buttonAdd.hidden = false } else if (self.lastContentOffset < scrollView.contentOffset.y && scrollView.contentOffset.y > 0) { // move down buttonAdd.hidden = true } // update the new position acquired self.lastContentOffset = scrollView.contentOffset.y` 

做这个:

 override func viewDidLoad(){ super.viewDidLoad(); var upGs = UISwipeGestureRecognizer(target: self, action: Selector("handleSwipes:")) var downGs = UISwipeGestureRecognizer(target: self, action: Selector("handleSwipes:")) upGs.direction = .Up downGs.direction = .Down super.view.addGestureRecognizer(upGs) super.view.addGestureRecognizer(downGs) } func handleSwipes(sender:UISwipeGestureRecognizer) { if (sender.direction == .Up) { println("Up") } if (sender.direction == .Down) { println("Down") } } 

对于Swift,我认为最简单最有力的就是像下面这样做。 它允许你跟踪方向改变的时间,只有一次改变时才作出反应。 另外,如果您需要在其他任何阶段查阅代码,则可以始终访问.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以跟踪任何方向。

我希望这可以帮助别人。

干杯

你可以做这样的事情:

 fileprivate var lastContentOffset: CGPoint = .zero func checkScrollDirection(_ scrollView: UIScrollView) -> UIScrollViewDirection { return lastContentOffset.y > scrollView.contentOffset.y ? .up : .down } 

和scrollViewDelegate:

 func scrollViewDidScroll(_ scrollView: UIScrollView) { switch checkScrollDirection(scrollView) { case .up: // move up case .down: // move down default: break } lastContentOffset = scrollView.contentOffset } 

我发现这是最简单和最灵活的选项(它也适用于UICollectionView和UITableView)。

 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 } } 

如果这不起作用,是否有0速度 – 在这种情况下,你将别无select,只能使用接受答案的存储属性解决scheme。