Skip to content

Instantly share code, notes, and snippets.

@Zhendryk
Created October 24, 2018 15:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Zhendryk/3c1fa91f2976fc9acfeea437f03a46be to your computer and use it in GitHub Desktop.
Save Zhendryk/3c1fa91f2976fc9acfeea437f03a46be to your computer and use it in GitHub Desktop.
Extension for UIView making AutoLayout a breeze
//
// UIView+AutoLayout.swift
//
// Created by Zhendryk on 10/24/18.
// Copyright © 2018 Zhendryk. All rights reserved.
//
import UIKit
extension UIView {
/// Returns the parent UIViewController of this UIView if it exists
var parentViewController: UIViewController? {
var parentResponder: UIResponder? = self
while parentResponder != nil {
parentResponder = parentResponder!.next
if let viewController = parentResponder as? UIViewController {
return viewController
}
}
return nil
}
/// Enables AutoLayout for this UIView
func enableAutoLayout() {
translatesAutoresizingMaskIntoConstraints = false
}
/// Disables AutoLayout for this UIView
func disableAutoLayout() {
translatesAutoresizingMaskIntoConstraints = true
}
/// Anchors this UIView to the given NSLayoutAxisAnchors with optional padding and size
///
/// - Parameters:
/// - top: The NSLayoutYAxisAnchor to anchor the top edge of this UIView to
/// - leading: The NSLayoutXAxisAnchor to anchor the leading (left) edge of this UIView to
/// - bottom: The NSLayoutYAxisAnchor to anchor the bottom edge of this UIView to
/// - trailing: The NSLayoutXAxisAnchor to anchor the trailing (right) edge of this UIView to
/// - padding: UIEdgeInsets describing the padding you want on the edges of this UIView
/// - size: The height and width you want this UIView to be
func anchor(top: NSLayoutYAxisAnchor?, leading: NSLayoutXAxisAnchor?, bottom: NSLayoutYAxisAnchor?, trailing: NSLayoutXAxisAnchor?, padding: UIEdgeInsets = .zero, size: CGSize = .zero) {
if let top = top {
topAnchor.constraint(equalTo: top, constant: padding.top).isActive = true
}
if let leading = leading {
leadingAnchor.constraint(equalTo: leading, constant: padding.left).isActive = true
}
if let bottom = bottom {
bottomAnchor.constraint(equalTo: bottom, constant: -padding.bottom).isActive = true
}
if let trailing = trailing {
trailingAnchor.constraint(equalTo: trailing, constant: -padding.right).isActive = true
}
if size.width != 0 {
widthAnchor.constraint(equalToConstant: size.width).isActive = true
}
if size.height != 0 {
heightAnchor.constraint(equalToConstant: size.height).isActive = true
}
}
/// Sets the height and width anchors of this UIView equal to the height and width anchors of the given UIView
///
/// - Parameter view: The view to set the size of this UIView equal to
func anchorEqualSize(to view: UIView) {
widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
heightAnchor.constraint(equalTo: view.heightAnchor).isActive = true
}
/// Constraints the width and height of this UIView to the given size
///
/// - Parameter size: The size to constrain this UIView to
func anchorConstantSize(size: CGSize) {
widthAnchor.constraint(equalToConstant: size.width).isActive = true
heightAnchor.constraint(equalToConstant: size.height).isActive = true
}
/// Sets the height and width anchors of this UIView equal to the height and width anchors of the given UIView multiplied by the given scale for each
///
/// - Parameters:
/// - view: The view to set the proportional size of this UIView to
/// - widthMultiplier: The scale relative to the given UIView for this UIView's width
/// - heightMultiplier: The scale relative to the given UIView for this UIView's height
func anchorProportionalSize(to view: UIView, widthMultiplier: CGFloat = 0, heightMultiplier: CGFloat = 0) {
if widthMultiplier != 0 {
widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: widthMultiplier).isActive = true
}
if heightMultiplier != 0 {
heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: heightMultiplier).isActive = true
}
}
/// Constrains this UIView to a square of the given proportional width to the given UIView
///
/// - Parameters:
/// - view: The view to reference for the proportional size
/// - widthMultiplier: The scaled width of this UIView relative to the given UIView
func anchorProportionalSquare(to view: UIView, widthMultiplier: CGFloat) {
self.anchorProportionalSize(to: view, widthMultiplier: widthMultiplier)
self.anchorHeightToWidth()
}
/// Anchors the width of this UIView equal to the height
func anchorWidthToHeight() {
widthAnchor.constraint(equalTo: heightAnchor).isActive = true
}
/// Anchors the height of this UIView equal to the width
func anchorHeightToWidth(){
heightAnchor.constraint(equalTo: widthAnchor).isActive = true
}
/// Expands this UIView to fill its container with optional padding
///
/// - Parameter padding: The amount of padding around each edge of this UIView
func fillSuperview(_ padding: UIEdgeInsets = .zero) {
anchor(top: superview?.topAnchor, leading: superview?.leadingAnchor, bottom: superview?.bottomAnchor, trailing: superview?.trailingAnchor, padding: padding)
}
/// Aligns the center of this UIView to the center of its superview if it exists
func alignCenterPointToSuperView() {
if let superCenter = superview?.center {
center = superCenter
}
}
/// Aligns both the centerYAnchor and centerXAnchor of this UIView to its superview if it exists
func centerInSuperview() {
if let superCenterX = superview?.centerXAnchor {
centerXAnchor.constraint(equalTo: superCenterX).isActive = true
}
if let superCenterY = superview?.centerYAnchor {
centerYAnchor.constraint(equalTo: superCenterY).isActive = true
}
}
/// Aligns the centerYAnchor of this UIView to its superview if it exists
func centerVerticallyInSuperview() {
if let superCenterY = superview?.centerYAnchor {
centerYAnchor.constraint(equalTo: superCenterY).isActive = true
}
}
/// Aligns the centerXAnchor of this UIView to its superview if it exists
func centerHorizontallyInSuperview() {
if let superCenterX = superview?.centerXAnchor {
centerXAnchor.constraint(equalTo: superCenterX).isActive = true
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment