Given a UIScrollView with any of its standard properties configured (e.g. contentInset), how can I get the minimum and maximum contentOffset?
I.e. when the user scrolls all the way up to the left, what will the contentOffset be reported as?
I.e. if the user were to scroll all the way down to the bottom right, what will the contentOffset be reported as?
Imagine we have the following UIScrollView:
500 x 500
200 x 200
(10, 10, 20, 20)
Calculated contentOffsets:
-contentInset.left
(-10)-contentInset.top
(-10)contentSize.width - bounds.width + contentInset.right
(320)contentSize.height - bounds.height + contentInset.bottom
(320)Normally a UIScrollView starts at contentOffset = (0, 0)
. However, when you add contentInsets, it starts offset by a negative amount. When you scroll the first position into view so that you don't see the contentInset, you'll be at contentOffset = (0,0)
.
A similar thing happens at the end, where instead of 300 being the max offset, 320 becomes the max.
func minContentOffset(scrollView: UIScrollView) -> CGPoint {
return CGPoint(
x: -scrollView.contentInset.left,
y: -scrollView.contentInset.top)
}
func maxContentOffset(scrollView: UIScrollView) -> CGPoint {
return CGPoint(
x: scrollView.contentSize.width - scrollView.bounds.width + scrollView.contentInset.right,
y: scrollView.contentSize.height - scrollView.bounds.height + scrollView.contentInset.bottom)
}
You could then create a function that uses both of those to determine if a scroll view is scrollable:
func canVerticallyScroll(scrollView: UIScrollView) -> Bool {
let scrollableHeight = maxContentOffset(scrollView: scrollView).y
- minContentOffset(scrollView: scrollView).y
let viewableHeight = scrollView.bounds.height
return viewableHeight < scrollableHeight
}
Or as an extension:
extension UIScrollView {
var minContentOffset: CGPoint {
return CGPoint(
x: -contentInset.left,
y: -contentInset.top)
}
var maxContentOffset: CGPoint {
return CGPoint(
x: contentSize.width - bounds.width + contentInset.right,
y: contentSize.height - bounds.height + contentInset.bottom)
}
func scrollToMinContentOffset(animated: Bool) {
setContentOffset(minContentOffset, animated: animated)
}
func scrollToMaxContentOffset(animated: Bool) {
setContentOffset(maxContentOffset, animated: animated)
}
}