Created
February 7, 2022 18:33
-
-
Save delannoyk/e9bd6b2a8ff6706eb71056f2f8d87d60 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
private final class ScrollViewBehaviorContainer: NSObject, UIScrollViewDelegate { | |
// MARK: Properties | |
var behaviors = [ScrollViewBehavior]() | |
// MARK: UIScrollViewDelegate | |
func scrollViewDidScroll(_ scrollView: UIScrollView) { | |
behaviors.forEach { $0.afterScrolling(scrollView) } | |
} | |
func scrollViewDidZoom(_ scrollView: UIScrollView) { | |
behaviors.forEach { $0.afterZooming(scrollView) } | |
} | |
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) { | |
behaviors.forEach { $0.beforeDraggingBegins(scrollView) } | |
} | |
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) { | |
behaviors.forEach { $0.beforeDraggingEnds(scrollView, velocity: velocity, targetContentOffset: targetContentOffset) } | |
} | |
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) { | |
behaviors.forEach { $0.afterDraggingEnds(scrollView, wilDecelerate: decelerate) } | |
} | |
func scrollViewWillBeginDecelerating(_ scrollView: UIScrollView) { | |
behaviors.forEach { $0.beforeDeceleratingBegins(scrollView) } | |
} | |
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { | |
behaviors.forEach { $0.afterDeceleratingEnds(scrollView) } | |
} | |
func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) { | |
behaviors.forEach { $0.afterScrollingAnimation(scrollView) } | |
} | |
func scrollViewWillBeginZooming(_ scrollView: UIScrollView, with view: UIView?) { | |
behaviors.forEach { $0.beforeZoomingBegins(scrollView, view: view) } | |
} | |
func scrollViewDidEndZooming(_ scrollView: UIScrollView, with view: UIView?, atScale scale: CGFloat) { | |
behaviors.forEach { $0.afterZoomingEnds(scrollView, view: view, scale: scale) } | |
} | |
func scrollViewDidScrollToTop(_ scrollView: UIScrollView) { | |
behaviors.forEach { $0.afterScrollingToTop(scrollView) } | |
} | |
func scrollViewDidChangeAdjustedContentInset(_ scrollView: UIScrollView) { | |
behaviors.forEach { $0.afterChangingAdjustedContentInset(scrollView) } | |
} | |
} | |
extension UIScrollView { | |
// MARK: Objective-C Runtime | |
private enum Keys { | |
static var behaviorContainer = "behaviorContainer" | |
} | |
private var behaviorContainer: ScrollViewBehaviorContainer { | |
if let container = objc_getAssociatedObject(self, &Keys.behaviorContainer) as? ScrollViewBehaviorContainer { | |
return container | |
} | |
let container = ScrollViewBehaviorContainer() | |
objc_setAssociatedObject(self, &Keys.behaviorContainer, container, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) | |
return container | |
} | |
// MARK: Public methods | |
func addBehavior(_ behavior: ScrollViewBehavior) { | |
behaviorContainer.behaviors.append(behavior) | |
} | |
func addBehaviors(_ behaviors: [ScrollViewBehavior]) { | |
behaviorContainer.behaviors.append(contentsOf: behaviors) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment