【问题标题】:UIScrollView as UIControlUIScrollView 作为 UIControl
【发布时间】:2018-06-12 09:59:16
【问题描述】:

我正在使用 UIScrollView 实现 UIControl。我希望在用户用手指滚动滚动视图时发送 .valueChanged 事件,否则不会。为此,我需要比较滚动发生时计算的 currentValue,如果它与以前的值不同,我会通过 sendActionsForControlEvents API 发送一个 .valueChanged 事件。我的问题:

(a) 在所有情况下,知道用户拖动滚动视图的最可靠方法是什么(滚动也可以在我的代码中使用自动化 API 发生)——scrollView.isDragging 或 scrollView.isTracking,或两者兼而有之?

(b) 有什么方法可以注意到 currentValue 的变化(不存储之前的值)?我正在使用 Swift 4 执行此操作,但它似乎没有给出旧值:

 private(set) public var currentValue = Int(0) {
    willSet (newValue) {
        NSLog("Old value \(currentValue), new \(newValue)")
    }
 }

【问题讨论】:

  • 1.为什么不简单地使用 didScroll 委托方法?当可见帧发生变化时应该触发它。将它与 isDragging 一起使用应该几乎可以解决您的问题。 2. 如果你只想跟踪用户滚动,那么减速呢?那时我相信 isDragging 已经是错误的。有一种委托方法可以为您提供结束拖动的信息,其中包括滚动视图将减速的布尔值。如果你也需要处理这个问题,我认为单独使用代表应该效果最好。
  • 我的问题是,有时我也会使用自动化 API 来设置 contentOffset -- scroller.setContentOffset(CGPoint(x: scroller.contentOffset.x, y: offset), animated: true)。这也调用了 scrollViewDidScroll:,对吗?当滚动条即将减速停止时触发减速 API。我使用这两种 API,但需要区分自动生成的和用户生成的。
  • 没错。这就是为什么你需要一个像isUserScrolling 这样的标志,最好在拖动开始时设置为true;如果减速为假,则在拖动结束时设置为假;减速结束时设置为 false。然后在didScroll 上使用这个isUserScrolling。当isUserScrolling 为真时,用户正在拖动。
  • 作为答案,您需要一个代表。不过,这可能比子类化更糟。我不确定没有它是否有稳定的解决方案,但您可能可以混合一些方法。

标签: ios swift uiscrollview swift4 uicontrol


【解决方案1】:

从使用委托的 cmets 来看,我认为可靠的解决方案应该类似于:

class MyClass: NSObject, UIScrollViewDelegate {

    private var isUserDragging: Bool = false

    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        if isUserDragging {
            // Should trigger only when scroll view visible frame changes and user is dragging
            print("User is dragging")
        }
    }

    func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
        isUserDragging = true // Should only be called when user starts dragging
    }

    func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
        if decelerate == false {
            isUserDragging = false // Disable user dragging only if no deceleration will be performed
        }
    }

    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        isUserDragging = false // When deceleration is done user is not dragging anymore
    }

}

现在您应该可以在scrollViewDidScroll 中获得您的活动了。

【讨论】:

    猜你喜欢
    • 2011-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-01
    • 1970-01-01
    • 2013-07-23
    相关资源
    最近更新 更多