Created
December 6, 2017 15:51
-
-
Save lessthanyouthink/c9e9ff9a24bc56180ac5c8f6bcbd9325 to your computer and use it in GitHub Desktop.
Pins a given scroll view’s width and height to its content size (and insets). Useful when you want to place a scroll view within another scroll view.
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
// | |
// ScrollViewPinner.swift | |
// | |
// Created by Charles Joseph on 2017-11-01. | |
// | |
import Foundation | |
import UIKit | |
/// Pins a given scroll view’s width and height to its content size (and insets). Useful when you want to place a scroll view within another scroll view. | |
class ScrollViewPinner: NSObject { | |
private(set) weak var scrollView: UIScrollView? | |
var active: Bool = true { | |
didSet { | |
width.isActive = active | |
height.isActive = active | |
scrollView?.isScrollEnabled = !active | |
} | |
} | |
private let width: NSLayoutConstraint | |
private let height: NSLayoutConstraint | |
init(scrollView: UIScrollView) { | |
self.scrollView = scrollView | |
scrollView.isScrollEnabled = false | |
width = scrollView.widthAnchor.constraint(equalToConstant: 0) | |
height = scrollView.heightAnchor.constraint(equalToConstant: 0) | |
NSLayoutConstraint.activate([width, height]) | |
super.init() | |
scrollView.addObserver(self, forKeyPath: "contentSize", options: [], context: nil) | |
scrollView.addObserver(self, forKeyPath: "contentInset", options: [], context: nil) | |
} | |
deinit { | |
scrollView?.removeObserver(self, forKeyPath: "contentSize") | |
scrollView?.removeObserver(self, forKeyPath: "contentInset") | |
} | |
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { | |
if (object as? UIScrollView) === scrollView && (keyPath == "contentSize" || keyPath == "contentInset") { | |
updateConstraints() | |
} | |
else { | |
super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context) | |
} | |
} | |
private func updateConstraints() { | |
guard let scrollView = scrollView else { | |
return | |
} | |
width.constant = scrollView.contentSize.width + scrollView.contentInset.left + scrollView.contentInset.right | |
height.constant = scrollView.contentSize.height + scrollView.contentInset.top + scrollView.contentInset.bottom | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment