Skip to content

Instantly share code, notes, and snippets.

@danielgalasko
Last active March 24, 2021 15:47
Show Gist options
  • Save danielgalasko/c645434dc60cb895a557 to your computer and use it in GitHub Desktop.
Save danielgalasko/c645434dc60cb895a557 to your computer and use it in GitHub Desktop.
A UIView extension for common auto layout constraints
extension UIView {
func addConstaintsToPinHorizontalEdgesToSuperView(padding: CGFloat = 0) {
prepareForConstraints()
self.superview!.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-(padding)-[view]-(padding)-|",
options: NSLayoutFormatOptions(0),
metrics: ["padding":padding],
views: ["view":self]))
}
func addConstaintsToPinVerticalEdgesToSuperView(padding: CGFloat = 0) {
prepareForConstraints()
self.superview!.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-(padding)-[view]-(padding)-|",
options: NSLayoutFormatOptions(0),
metrics: ["padding":padding],
views: ["view":self]))
}
func addConstaintsToCenterVertically() {
prepareForConstraints()
self.superview!.addConstraint(NSLayoutConstraint(item: self,
attribute: .CenterY,
relatedBy: .Equal,
toItem: self.superview!,
attribute: .CenterY,
multiplier: 1.0, constant: 0))
}
func addConstaintsToCenterHorizontally() {
prepareForConstraints()
self.superview!.addConstraint(NSLayoutConstraint(item: self,
attribute: .CenterX,
relatedBy: .Equal,
toItem: self.superview!,
attribute: .CenterX,
multiplier: 1.0, constant: 0))
}
func addConstaintsToPinLeadingToSuperview(constant: CGFloat) -> NSLayoutConstraint {
prepareForConstraints()
let constraint = NSLayoutConstraint(item: self,
attribute: .Leading,
relatedBy: .Equal,
toItem: self.superview!,
attribute: .Leading,
multiplier: 1, constant: constant)
self.superview!.addConstraint(constraint)
return constraint
}
func addConstaintsToPinTrailingToSuperview(constant: CGFloat) -> NSLayoutConstraint {
prepareForConstraints()
let constraint = NSLayoutConstraint(item: self,
attribute: .Trailing,
relatedBy: .Equal,
toItem: self.superview!,
attribute: .Trailing,
multiplier: 1, constant: constant)
self.superview!.addConstraint(constraint)
return constraint
}
func addConstaintsToPinTopToSuperview(constant: CGFloat) -> NSLayoutConstraint {
prepareForConstraints()
let constraint = NSLayoutConstraint(item: self,
attribute: .Top,
relatedBy: .Equal,
toItem: self.superview!,
attribute: .Top,
multiplier: 1, constant: constant)
self.superview!.addConstraint(constraint)
return constraint
}
func addConstaintsToPinTopToView(view:UIView,constant: CGFloat) -> NSLayoutConstraint {
prepareForConstraints()
let constraint = NSLayoutConstraint(item: self,
attribute: .Top,
relatedBy: .Equal,
toItem: view,
attribute: .Top,
multiplier: 1, constant: constant)
self.superview!.addConstraint(constraint)
return constraint
}
func addConstaintsToPinBottomToView(view:UIView,constant: CGFloat) -> NSLayoutConstraint {
prepareForConstraints()
let constraint = NSLayoutConstraint(item: self,
attribute: .Bottom,
relatedBy: .Equal,
toItem: view,
attribute: .Bottom,
multiplier: 1, constant: constant)
self.superview!.addConstraint(constraint)
return constraint
}
func addConstaintsToFillSuperviewWithPadding(padding: CGFloat = 0) {
prepareForConstraints()
addConstaintsToPinHorizontalEdgesToSuperView(padding: padding)
addConstaintsToPinVerticalEdgesToSuperView(padding: padding)
}
private func prepareForConstraints() {
self.setTranslatesAutoresizingMaskIntoConstraints(false)
if superview == nil {
assert(false, "You need to have a superview before you can add contraints")
}
}
}
@rafiki270
Copy link

rafiki270 commented Jun 6, 2018

swift 4.2 update + some refactors to drop force unwraps + accessing functionality through view.layout. pinHorizontalEdgesToSuperView() for example + some smallish refactors:

struct Layout {
    
    let element: UIView
    
    init(_ element: UIView) {
        self.element = element
    }
    
    // MARK: Layout
    
    @discardableResult func pinHorizontalEdgesToSuperView(padding: CGFloat = 0) -> [NSLayoutConstraint] {
        let constraints = NSLayoutConstraint.constraints(withVisualFormat: "H:|-(padding)-[view]-(padding)-|",
                                                        options: NSLayoutConstraint.FormatOptions(rawValue: 0),
                                                        metrics: ["padding": padding],
                                                        views: ["view": element])
        safeSuperview().addConstraints(constraints)
        return constraints
    }
    
    @discardableResult func pinVerticalEdgesToSuperView(padding: CGFloat = 0) -> [NSLayoutConstraint] {
        let constraints = NSLayoutConstraint.constraints(withVisualFormat: "V:|-(padding)-[view]-(padding)-|",
                                                        options: NSLayoutConstraint.FormatOptions(rawValue: 0),
                                                        metrics: ["padding": padding],
                                                        views: ["view": element])
        safeSuperview().addConstraints(constraints)
        return constraints
    }
    
    @discardableResult func centerVertically() -> NSLayoutConstraint {
        let constraint = NSLayoutConstraint(item: element,
                                            attribute: .centerY,
                                            relatedBy: .equal,
                                            toItem: safeSuperview(),
                                            attribute: .centerY,
                                            multiplier: 1.0, constant: 0)
        safeSuperview().addConstraint(constraint)
        return constraint
    }
    
    @discardableResult func centerHorizontally() -> NSLayoutConstraint {
        let constraint = NSLayoutConstraint(item: element,
                                            attribute: .centerX,
                                            relatedBy: .equal,
                                            toItem: safeSuperview(),
                                            attribute: .centerX,
                                            multiplier: 1.0, constant: 0)
        safeSuperview().addConstraint(constraint)
        return constraint
    }
    
    @discardableResult func pinLeadingToSuperview(constant: CGFloat) -> NSLayoutConstraint {
        let constraint = NSLayoutConstraint(item: element,
                                            attribute: .leading,
                                            relatedBy: .equal,
                                            toItem: safeSuperview(),
                                            attribute: .leading,
                                            multiplier: 1, constant: constant)
        
        safeSuperview().addConstraint(constraint)
        return constraint
    }
    
    @discardableResult func pinTrailingToSuperview(constant: CGFloat) -> NSLayoutConstraint {
        let constraint = NSLayoutConstraint(item: element,
                                            attribute: .trailing,
                                            relatedBy: .equal,
                                            toItem: safeSuperview(),
                                            attribute: .trailing,
                                            multiplier: 1, constant: constant)
        safeSuperview().addConstraint(constraint)
        return constraint
    }
    
    @discardableResult func pinTopToSuperview(constant: CGFloat) -> NSLayoutConstraint {
        let constraint = NSLayoutConstraint(item: element,
                                            attribute: .top,
                                            relatedBy: .equal,
                                            toItem: safeSuperview(),
                                            attribute: .top,
                                            multiplier: 1, constant: constant)
        safeSuperview().addConstraint(constraint)
        return constraint
    }
    
    @discardableResult func pinTopToView(view:UIView,constant: CGFloat) -> NSLayoutConstraint {
        let constraint = NSLayoutConstraint(item: element,
                                            attribute: .top,
                                            relatedBy: .equal,
                                            toItem: view,
                                            attribute: .top,
                                            multiplier: 1, constant: constant)
        safeSuperview().addConstraint(constraint)
        return constraint
    }
    
    @discardableResult func pinBottomToView(view:UIView,constant: CGFloat) -> NSLayoutConstraint {
        let constraint = NSLayoutConstraint(item: element,
                                            attribute: .bottom,
                                            relatedBy: .equal,
                                            toItem: view,
                                            attribute: .bottom,
                                            multiplier: 1, constant: constant)
        safeSuperview().addConstraint(constraint)
        return constraint
    }
    
    func fillSuperview(padding: CGFloat = 0) {
        safeSuperview()
        pinHorizontalEdgesToSuperView(padding: padding)
        pinVerticalEdgesToSuperView(padding: padding)
    }
    
    @discardableResult private func safeSuperview() -> UIView {
        element.translatesAutoresizingMaskIntoConstraints = false
        guard let view = element.superview else {
            fatalError("You need to have a superview before you can add contraints")
        }
        return view
    }
    
}


extension UIView {
    
    var layout: Layout {
        return Layout(self)
    }
    
}

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