【问题标题】:UIScrollView snap-to-position while scrolling滚动时 UIScrollView 对齐位置
【发布时间】:2016-01-03 03:48:27
【问题描述】:

我正在尝试实现一个滚动视图,该视图在滚动时捕捉到点。

我在这里看到的所有关于在用户结束拖动滚动条“之后”捕捉到某个点的帖子。我想让它在拖动过程中捕捉。

到目前为止,我有这个可以在拖动后停止惯性并且效果很好:

func scrollViewWillEndDragging(scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
      targetContentOffset.memory = scrollView.contentOffset
}

我试过了,但没有按预期工作:

    var scrollSnapHeight : CGFloat = myScrollView.contentSize.height/10

scrollViewDidScroll:

func scrollViewDidScroll(scrollView: UIScrollView) {
    let remainder : CGFloat = scrollView.contentOffset.y % scrollSnapHeight
    var scrollPoint : CGPoint = scrollView.contentOffset
    if remainder != 0 && scrollView.dragging
    {
        if self.lastOffset > scrollView.contentOffset.y //Scrolling Down
        {
            scrollPoint.y += (scrollSnapHeight - remainder)
            NSLog("scrollDown")
        }
        else //Scrolling Up
        {
            scrollPoint.y -= (scrollSnapHeight - remainder)
        }
        scrollView .setContentOffset(scrollPoint, animated: true)
    }
    self.lastOffset = scrollView.contentOffset.y;
}

【问题讨论】:

    标签: ios swift uiscrollview paging scroll-snap-points


    【解决方案1】:

    此方法将启用/禁用UIScrollViewscrollEnabled 属性。

    当scrollView 滚动到给定scrollSnapHeight 之外时,将scrollEnabled 设置为false。这将停止滚动。然后再次启用滚动以进行下一次拖动。

    extension ViewController: UIScrollViewDelegate {
    
        func scrollViewDidScroll(scrollView: UIScrollView) {
    
            if scrollView.contentOffset.y > lastOffset + scrollSnapHeight {
                scrollView.scrollEnabled = false
            } else if scrollView.contentOffset.y < lastOffset - scrollSnapHeight {
                scrollView.scrollEnabled = false
            }
        }
    
        func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) {
    
            guard !decelerate else {
                return
            }
    
            setContentOffset(scrollView)
        }
    
        func scrollViewWillBeginDecelerating(scrollView: UIScrollView) {
    
            setContentOffset(scrollView)
        }
    }
    

    func setContentOffset(scrollView: UIScrollView) {
    
        let stopOver = scrollSnapHeight
        var y = round(scrollView.contentOffset.y / stopOver) * stopOver
        y = max(0, min(y, scrollView.contentSize.height - scrollView.frame.height))
        lastOffset = y
    
        scrollView.setContentOffset(CGPointMake(scrollView.contentOffset.x, y), animated: true)
    
        scrollView.scrollEnabled = true
    }
    

    【讨论】:

    • 当我尝试这个时,捕捉后,用户必须抬起手指,然后再次开始拖动。有没有不提升修饰的方法?
    • @gizmodo 我听不懂。对齐位置意味着用户可以拖动但滚动视图不会滚动。现在你想让scrollView再次滚动哪个事件?
    • @gizmodo 如果你想在用户停止拖动 scrollView 后捕捉,stackoverflow.com/a/35197919/1378447
    • 当我尝试您的示例代码时,它按我想要的方式工作,只是在捕捉后,滚动视图将停止滚动。您必须抬起手指并再次开始滚动才能恢复。如果您查看 Apple 的 iOS 9 照片应用程序的编辑功能,您可以看到它们无需抬起即可快速恢复。它捕捉到默认位置。看起来 scrollView.scrollEnabled = false 会使平移结束。
    • @gizmodo 抱歉,我在拖入照片应用的编辑功能时找不到捕捉。我认为您对滚动禁用结束平移手势是正确的。
    【解决方案2】:

    子类 UIScrollView/UICollectionView

    此解决方案不需要您抬起手指即可在滚动时解开并工作。如果您需要垂直滚动而不是水平滚动,只需将 x 与 y 交换即可。

    snapPoint 设置为您希望快照中心所在的内容偏移量。

    snapOffset 设置为您希望在 snapPoint 周围发生捕捉的半径。

    如果您需要知道 scrollView 是否已捕捉,只需检查 isSnapped 变量即可。

    class UIScrollViewSnapping : UIScrollView {
        public var snapPoint: CGPoint?
        public var snapOffset: CGFloat?
        public var isSnapped = false
        
        public override var contentOffset: CGPoint {
            set {
                if let snapPoint = self.snapPoint,
                    let snapOffset = self.snapOffset,
                    newValue.x > snapPoint.x - snapOffset,
                    newValue.x < snapPoint.x + snapOffset {
                    self.isSnapped = true
                    super.contentOffset = snapPoint
                }
                else {
                    self.isSnapped = false
                    super.contentOffset = newValue
                }
            }
            get {
                return super.contentOffset
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-24
      • 1970-01-01
      • 1970-01-01
      • 2014-01-23
      相关资源
      最近更新 更多