Skip to content

Instantly share code, notes, and snippets.

@abhi21git
Last active May 14, 2023 13:05
Show Gist options
  • Save abhi21git/9e23916f3399c6f70f859f698d3e8915 to your computer and use it in GitHub Desktop.
Save abhi21git/9e23916f3399c6f70f859f698d3e8915 to your computer and use it in GitHub Desktop.
Add subviews with constraints for cleaner code
//
// UIView+AddSubview+Constraints.swift
//
// Created by Abhishek Maurya on 22/04/23.
//
extension UIView {
func addSubview(_ subView: UIView, considerSafeArea: Bool = false, with constraints: Array<Constraints>) -> [NSLayoutConstraint] {
addSubview(subView)
return subView.addConstraints(in: self, considerSafeArea: considerSafeArea, with: constraints)
}
func addConstraints(in view: UIView, considerSafeArea: Bool = false, with constraints: Array<Constraints>) -> [NSLayoutConstraint] {
translatesAutoresizingMaskIntoConstraints = false
return constraints.map({ constraint in
switch constraint {
case .leading(let constant, let anchor, let priority):
let leading = anchor ?? (considerSafeArea ? view.safeAreaLayoutGuide.leadingAnchor : view.leadingAnchor)
return leading.constraint(equalTo: leadingAnchor, constant: -constant).atPriority(priority)
case .top(let constant, let anchor, let priority):
let top = anchor ?? (considerSafeArea ? view.safeAreaLayoutGuide.topAnchor : view.topAnchor)
return top.constraint(equalTo: topAnchor, constant: -constant).atPriority(priority)
case .trailing(let constant, let anchor, let priority):
let trailing = anchor ?? (considerSafeArea ? view.safeAreaLayoutGuide.trailingAnchor : view.trailingAnchor)
return trailing.constraint(equalTo: trailingAnchor, constant: constant).atPriority(priority)
case .bottom(let constant, let anchor, let priority):
let bottom = anchor ?? (considerSafeArea ? view.safeAreaLayoutGuide.bottomAnchor : view.bottomAnchor)
return bottom.constraint(equalTo: bottomAnchor, constant: constant).atPriority(priority)
case .centerX(let constant, let anchor, let priority):
let centerX = anchor ?? (considerSafeArea ? view.safeAreaLayoutGuide.centerXAnchor : view.centerXAnchor)
return centerX.constraint(equalTo: centerXAnchor, constant: constant).atPriority(priority)
case .centerY(let constant, let anchor, let priority):
let centerY = anchor ?? (considerSafeArea ? view.safeAreaLayoutGuide.centerYAnchor : view.centerYAnchor)
return centerY.constraint(equalTo: centerYAnchor, constant: constant).atPriority(priority)
case .height(let constant, let equalTo, let priority):
if let height = equalTo {
return heightAnchor.constraint(equalTo: height, constant: constant).atPriority(priority)
} else {
return heightAnchor.constraint(equalToConstant: constant).atPriority(priority)
}
case .width(let constant, let equalTo, let priority):
if let width = equalTo {
return widthAnchor.constraint(equalTo: width, constant: constant).atPriority(priority)
} else {
return widthAnchor.constraint(equalToConstant: constant).atPriority(priority)
}
case .aspectRatio(let multiplier, let priority):
return widthAnchor.constraint(equalTo: heightAnchor, multiplier: multiplier).atPriority(priority)
}
})
}
}
public extension NSLayoutConstraint {
func atPriority(_ priority: UILayoutPriority) -> Self {
self.priority = priority
return self
}
}
public enum Constraints {
case leading(constant: CGFloat = 0, from: NSLayoutXAxisAnchor? = nil, priority: UILayoutPriority = .required)
case top(constant: CGFloat = 0, from: NSLayoutYAxisAnchor? = nil, priority: UILayoutPriority = .required)
case trailing(constant: CGFloat = 0, from: NSLayoutXAxisAnchor? = nil, priority: UILayoutPriority = .required)
case bottom(constant: CGFloat = 0, from: NSLayoutYAxisAnchor? = nil, priority: UILayoutPriority = .required)
case centerX(constant: CGFloat = 0, from: NSLayoutXAxisAnchor? = nil, priority: UILayoutPriority = .required)
case centerY(constant: CGFloat = 0, from: NSLayoutYAxisAnchor? = nil, priority: UILayoutPriority = .required)
case height(constant: CGFloat = 0, equalTo: NSLayoutDimension? = nil, priority: UILayoutPriority = .required)
case width(constant: CGFloat = 0, equalTo: NSLayoutDimension? = nil, priority: UILayoutPriority = .required)
case aspectRatio(multiplier: CGFloat = 1, priority: UILayoutPriority = .required)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment