Skip to content

Instantly share code, notes, and snippets.

@stoqn4opm
Created May 21, 2020 05:57
Show Gist options
  • Save stoqn4opm/6d2f8bc765a515a5cc3d81e4a4cbceab to your computer and use it in GitHub Desktop.
Save stoqn4opm/6d2f8bc765a515a5cc3d81e4a4cbceab to your computer and use it in GitHub Desktop.
`UICollectionView` subclass that makes all its instances have the same scroll offset. When one instance scrolls all others will follow to the same content offset.
import UIKit
// MARK: - Notifications
extension Notification.Name {
/// Posted everytime when a `SharedOffsetCollectionView` scrolls. The object is the instances that got scrolled.
fileprivate static let didScroll = Notification.Name(rawValue: "SharedContentOffset.didScroll")
}
// MARK: - Class Definition
/// `UICollectionView` subclass that makes all its instances have the same scroll offset.
/// When one instance scrolls all others will follow to the same content offset.
class SharedOffsetCollectionView: UICollectionView {
/// Simple flag used for internal logic control.
private var shouldTrack = true
override var contentOffset: CGPoint {
willSet {
NotificationCenter.default.removeObserver(self, name: .didScroll, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(scrollOccured(_:)), name: .didScroll, object: nil)
}
didSet {
guard shouldTrack == true else { return }
NotificationCenter.default.post(name: .didScroll, object: self)
}
}
deinit {
NotificationCenter.default.removeObserver(self, name: .didScroll, object: nil)
}
}
// MARK: - Notifications
extension SharedOffsetCollectionView {
/// Called when a `SharedOffsetCollectionView` scrolls.
/// It sets the content offset of other instances to the one that got scrolled
/// while making them not track that change to avoid recursion.
@objc private func scrollOccured(_ notification: Notification) {
guard let scrollView = notification.object as? UIScrollView else { return }
guard scrollView != self else { return }
shouldTrack = false
setContentOffset(scrollView.contentOffset, animated: false)
shouldTrack = true
}
}
@stoqn4opm
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment