|  | 
|  | 1 | +import UIKit | 
|  | 2 | + | 
|  | 3 | +/** | 
|  | 4 | + Scroll delegate used to control underlying TabView's collection view. | 
|  | 5 | + */ | 
|  | 6 | +class PagerScrollDelegate: NSObject, UIScrollViewDelegate, UICollectionViewDelegate { | 
|  | 7 | +  // Store the original delegate to forward calls | 
|  | 8 | +  weak var originalDelegate: UICollectionViewDelegate? | 
|  | 9 | +  weak var delegate: PagerViewProviderDelegate? | 
|  | 10 | +  var orientation: UICollectionView.ScrollDirection = .horizontal | 
|  | 11 | +   | 
|  | 12 | +  func scrollViewDidScroll(_ scrollView: UIScrollView) { | 
|  | 13 | +    let isHorizontal = orientation == .horizontal | 
|  | 14 | +    let pageSize = isHorizontal ? scrollView.frame.width : scrollView.frame.height | 
|  | 15 | +    let contentOffset = isHorizontal ? scrollView.contentOffset.x : scrollView.contentOffset.y | 
|  | 16 | +     | 
|  | 17 | +    guard pageSize > 0 else { return } | 
|  | 18 | +     | 
|  | 19 | +    let offset = contentOffset.truncatingRemainder(dividingBy: pageSize) / pageSize | 
|  | 20 | +    let position = round(contentOffset / pageSize - offset) | 
|  | 21 | +     | 
|  | 22 | +    let eventData = OnPageScrollEventData(position: position, offset: offset) | 
|  | 23 | +    delegate?.onPageScroll(data: eventData) | 
|  | 24 | +    originalDelegate?.scrollViewDidScroll?(scrollView) | 
|  | 25 | +  } | 
|  | 26 | +   | 
|  | 27 | +  func scrollViewWillBeginDragging(_ scrollView: UIScrollView) { | 
|  | 28 | +    delegate?.onPageScrollStateChanged(state: .dragging) | 
|  | 29 | +    originalDelegate?.scrollViewWillBeginDragging?(scrollView) | 
|  | 30 | +  } | 
|  | 31 | +   | 
|  | 32 | +  func scrollViewWillBeginDecelerating(_ scrollView: UIScrollView) { | 
|  | 33 | +    delegate?.onPageScrollStateChanged(state: .settling) | 
|  | 34 | +    originalDelegate?.scrollViewWillBeginDecelerating?(scrollView) | 
|  | 35 | +  } | 
|  | 36 | +   | 
|  | 37 | +  func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { | 
|  | 38 | +    delegate?.onPageScrollStateChanged(state: .idle) | 
|  | 39 | +    originalDelegate?.scrollViewDidEndDecelerating?(scrollView) | 
|  | 40 | +  } | 
|  | 41 | +   | 
|  | 42 | +  func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) { | 
|  | 43 | +    delegate?.onPageScrollStateChanged(state: .idle) | 
|  | 44 | +    originalDelegate?.scrollViewDidEndScrollingAnimation?(scrollView) | 
|  | 45 | +  } | 
|  | 46 | +   | 
|  | 47 | +  func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) { | 
|  | 48 | +    if !decelerate { | 
|  | 49 | +      delegate?.onPageScrollStateChanged(state: .idle) | 
|  | 50 | +    } | 
|  | 51 | +    originalDelegate?.scrollViewDidEndDragging?(scrollView, willDecelerate: decelerate) | 
|  | 52 | +  } | 
|  | 53 | +   | 
|  | 54 | +  func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) { | 
|  | 55 | +    originalDelegate?.collectionView?(collectionView, didEndDisplaying: cell, forItemAt: indexPath) | 
|  | 56 | +  } | 
|  | 57 | +   | 
|  | 58 | +  func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) { | 
|  | 59 | +    originalDelegate?.collectionView?(collectionView, willDisplay: cell, forItemAt: indexPath) | 
|  | 60 | +  } | 
|  | 61 | +   | 
|  | 62 | +  override func responds(to aSelector: Selector!) -> Bool { | 
|  | 63 | +    let handledSelectors: [Selector] = [ | 
|  | 64 | +      #selector(scrollViewDidScroll(_:)), | 
|  | 65 | +      #selector(scrollViewWillBeginDragging(_:)), | 
|  | 66 | +      #selector(scrollViewWillBeginDecelerating(_:)), | 
|  | 67 | +      #selector(scrollViewDidEndDecelerating(_:)), | 
|  | 68 | +      #selector(scrollViewDidEndScrollingAnimation(_:)), | 
|  | 69 | +      #selector(scrollViewDidEndDragging(_:willDecelerate:)), | 
|  | 70 | +      #selector(collectionView(_:didEndDisplaying:forItemAt:)), | 
|  | 71 | +      #selector(collectionView(_:willDisplay:forItemAt:)) | 
|  | 72 | +    ] | 
|  | 73 | +     | 
|  | 74 | +    if handledSelectors.contains(aSelector) { | 
|  | 75 | +      return true | 
|  | 76 | +    } | 
|  | 77 | +    return originalDelegate?.responds(to: aSelector) ?? false | 
|  | 78 | +  } | 
|  | 79 | +   | 
|  | 80 | +  override func forwardingTarget(for aSelector: Selector!) -> Any? { | 
|  | 81 | +    let handledSelectors: [Selector] = [ | 
|  | 82 | +      #selector(scrollViewDidScroll(_:)), | 
|  | 83 | +      #selector(scrollViewWillBeginDragging(_:)), | 
|  | 84 | +      #selector(scrollViewWillBeginDecelerating(_:)), | 
|  | 85 | +      #selector(scrollViewDidEndDecelerating(_:)), | 
|  | 86 | +      #selector(scrollViewDidEndScrollingAnimation(_:)), | 
|  | 87 | +      #selector(scrollViewDidEndDragging(_:willDecelerate:)), | 
|  | 88 | +      #selector(collectionView(_:didEndDisplaying:forItemAt:)), | 
|  | 89 | +      #selector(collectionView(_:willDisplay:forItemAt:)) | 
|  | 90 | +    ] | 
|  | 91 | +     | 
|  | 92 | +    if handledSelectors.contains(aSelector) { | 
|  | 93 | +      return nil | 
|  | 94 | +    } | 
|  | 95 | +    return originalDelegate | 
|  | 96 | +  } | 
|  | 97 | +} | 
|  | 98 | + | 
0 commit comments