Skip to content

Instantly share code, notes, and snippets.

@lessthanyouthink
Created December 6, 2017 15:51
Show Gist options
  • Save lessthanyouthink/c9e9ff9a24bc56180ac5c8f6bcbd9325 to your computer and use it in GitHub Desktop.
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.
//
// 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