How to stop scrolling

Updated
Apr 10, 2021 10:10 AM
Created
Apr 10, 2021 10:09 AM
Tags
SwiftUIKit.framework
Keywords


final class ScrollController {
  
  private var scrollObserver: NSKeyValueObservation?
  private var shouldStop: Bool = false
  private var previousValue: CGPoint?
  
  init() {
    
  }
  
  func lockScrolling() {
    shouldStop = true
  }
  
  func unlockScrolling() {
    shouldStop = false
  }
  
  func startTracking(scrollView: UIScrollView) {
    scrollObserver?.invalidate()
    scrollObserver = scrollView.observe(\.contentOffset, options: .old) { [weak self, weak _scrollView = scrollView] scrollView, change in
      
      guard let scrollView = _scrollView else { return }
      guard let self = self else { return }
      self.handleScrollViewEvent(scrollView: scrollView, change: change)
    }
  }
  
  func endTracking() {
    scrollObserver?.invalidate()
    scrollObserver = nil
  }
  
  private func handleScrollViewEvent(scrollView: UIScrollView, change: NSKeyValueObservedChange<CGPoint>) {
    
    // For debugging
    
    guard let oldValue = change.oldValue else { return }
    
    guard shouldStop else {
      scrollView.showsVerticalScrollIndicator = true
      return
    }
    
    guard scrollView.contentOffset != oldValue else { return }
    
    guard oldValue != previousValue else { return }
    
    previousValue = scrollView.contentOffset
    
    scrollView.setContentOffset(oldValue, animated: false)
    scrollView.showsVerticalScrollIndicator = false
  }
  
}