Skip to content

Instantly share code, notes, and snippets.

@magicmark
Last active August 29, 2015 14:23
Show Gist options
  • Save magicmark/6fe06426944cff6a7b86 to your computer and use it in GitHub Desktop.
Save magicmark/6fe06426944cff6a7b86 to your computer and use it in GitHub Desktop.
Allow dynamic UIScrollView content view sizes to work with AutoLayout
//
// DynamicScrollViewContainer.swift
// magicmark
//
// Created by Mark Larah on 25/05/2015.
// Copyright (c) 2015 Mark. All rights reserved.
//
import UIKit
class DynamicScrollViewContainer: UIView {
var childScroll: UIScrollView?
override func didMoveToSuperview() {
super.didMoveToSuperview()
setUpChildScroll()
}
var delegate: DynamicScrollViewDelegate?
func setUpChildScroll() {
childScroll = UIScrollView(frame: CGRect(x: 0, y: 0, width: 1, height: 1))
self.addSubview(childScroll!)
// Set up constraints to stretch view to superview's edges
var scrollConstraint1 = NSLayoutConstraint(
item: childScroll!,
attribute: NSLayoutAttribute.CenterY,
relatedBy: NSLayoutRelation.Equal,
toItem: self,
attribute: NSLayoutAttribute.CenterY,
multiplier: 1.0,
constant: 0
)
var scrollConstraint2 = NSLayoutConstraint(
item: childScroll!,
attribute: NSLayoutAttribute.Height,
relatedBy: NSLayoutRelation.Equal,
toItem: self,
attribute: NSLayoutAttribute.Height,
multiplier: 1.0,
constant: 0
)
var scrollConstraint3 = NSLayoutConstraint(
item: childScroll!,
attribute: NSLayoutAttribute.Width,
relatedBy: NSLayoutRelation.Equal,
toItem: self,
attribute: NSLayoutAttribute.Width,
multiplier: 1.0,
constant: 0
)
var scrollConstraint4 = NSLayoutConstraint(
item: childScroll!,
attribute: NSLayoutAttribute.CenterX,
relatedBy: NSLayoutRelation.Equal,
toItem: self,
attribute: NSLayoutAttribute.CenterX,
multiplier: 1.0,
constant: 0
)
childScroll!.setTranslatesAutoresizingMaskIntoConstraints(false)
superview!.addConstraint(scrollConstraint1)
superview!.addConstraint(scrollConstraint2)
superview!.addConstraint(scrollConstraint3)
superview!.addConstraint(scrollConstraint4)
}
func scrollToTop() {
childScroll!.setContentOffset(CGPointMake(0, -childScroll!.contentInset.top), animated: false)
}
}
//
// DynamicUIView.swift
// magicmark
//
// Created by Mark Larah on 25/05/2015.
// Copyright (c) 2015 Mark. All rights reserved.
//
import UIKit
// Implement this protocol in the ViewController as shown in ViewController.swift
protocol DynamicUIViewDelegate {
func didLayout(view: DynamicUIView)
}
class DynamicUIView: UIView {
var delegate: DynamicUIViewDelegate?
override func layoutSubviews() {
super.layoutSubviews()
delegate?.didLayout(self)
}
override func didMoveToSuperview() {
super.didMoveToSuperview()
setConstraints()
}
func setConstraints() {
if superview == nil {
return ;
}
self.setTranslatesAutoresizingMaskIntoConstraints(false)
var viewConstraint1 = NSLayoutConstraint(
item: self,
attribute: NSLayoutAttribute.Top,
relatedBy: NSLayoutRelation.Equal,
toItem: superview!,
attribute: NSLayoutAttribute.Top,
multiplier: 1.0,
constant: 0
)
var viewConstraint2 = NSLayoutConstraint(
item: self,
attribute: NSLayoutAttribute.Width,
relatedBy: NSLayoutRelation.Equal,
toItem: superview!,
attribute: NSLayoutAttribute.Width,
multiplier: 1.0,
constant: 0
)
superview!.addConstraint(viewConstraint1)
superview!.addConstraint(viewConstraint2)
}
}
//
// ViewController.swift
// Chabad
//
// Created by Mark Larah on 25/05/2015.
// Copyright (c) 2015 Mark. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
@IBOutlet var pagesContainer: DynamicScrollViewContainer!
@IBOutlet var page1: DynamicUIView!
@IBOutlet var page2: DynamicUIView!
override func viewDidLoad() {
super.viewDidLoad()
page1.delegate = self
page2.delegate = self
}
func setCorrectScrollViewSize (pageView: UIView) {
let lowestSubViewHeight = pageView.getLowestSubView().getBottomY()
// Plus 9 for padding text at the bottom. You can change this conditionally
let heightOfView = lowestSubViewHeight + 9
pagesContainer!.childScroll!.contentSize = CGSize(width: UIScreen.mainScreen().bounds.width, height: heightOfView)
pagesContainer!.scrollToTop()
}
}
// MARK - DynamicUIViewDelegate
extension ViewController: DynamicUIViewDelegate {
func didLayout(view: DynamicUIView) {
setCorrectScrollViewSize(view)
}
}
// MARK - UIView
extension UIView {
func getBottomY () -> CGFloat {
return self.frame.origin.y + self.frame.height
}
func getLowestSubView () -> UIView {
var minView: UIView = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
for subview in self.subviews {
if (subview as! UIView).getBottomY() > minView.getBottomY() {
minView = subview as! UIView
}
}
return minView
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment