Skip to content

Instantly share code, notes, and snippets.

@bernardonigbinde
Created May 30, 2021 12:07
Show Gist options
  • Save bernardonigbinde/04e3d0e3eb4b5774c785b1451e349142 to your computer and use it in GitHub Desktop.
Save bernardonigbinde/04e3d0e3eb4b5774c785b1451e349142 to your computer and use it in GitHub Desktop.
UIView extension - Auto Layout Helper
import UIKit
extension UIView {
func bottom(to view: UIView, offset: CGFloat = 0.0, usingSafeArea: Bool = false) {
constrain(bottomAnchor, to: usingSafeArea ? view.safeAreaLayoutGuide.bottomAnchor : view.bottomAnchor, of: view, offset: offset)
}
func topToBottom(of view: UIView, offset: CGFloat = 0.0, usingSafeArea: Bool = false) {
constrain(topAnchor, to: usingSafeArea ? view.safeAreaLayoutGuide.bottomAnchor : view.bottomAnchor, of: view, offset: offset)
}
func top(to view: UIView, offset: CGFloat = 0.0, usingSafeArea: Bool = false) {
constrain(topAnchor, to: usingSafeArea ? view.safeAreaLayoutGuide.topAnchor : view.topAnchor, of: view, offset: offset)
}
func right(to view: UIView, offset: CGFloat = 0.0, usingSafeArea: Bool = false) {
constrain(rightAnchor, to: usingSafeArea ? view.safeAreaLayoutGuide.rightAnchor : view.rightAnchor, of: view, offset: offset)
}
func left(to view: UIView, offset: CGFloat = 0.0, usingSafeArea: Bool = false) {
constrain(leftAnchor, to: usingSafeArea ? view.safeAreaLayoutGuide.leftAnchor : view.leftAnchor, of: view, offset: offset)
}
func bottomToTop(of view: UIView, offset: CGFloat = 0.0) {
translatesAutoresizingMaskIntoConstraints = false
constrain(bottomAnchor, to: view.topAnchor, of: view, offset: offset)
}
func rightToLeft(of view: UIView?, offset: CGFloat = 0.0) {
constrain(rightAnchor, to: view?.leftAnchor, of: view, offset: offset)
}
func leftToRight(of view: UIView?, offset: CGFloat = 0.0) {
constrain(leftAnchor, to: view?.rightAnchor, of: view, offset: offset)
}
func centerX(to view: UIView, offset: CGFloat = 0.0) {
constrain(centerXAnchor, to: view.centerXAnchor, of: view, offset: offset)
}
func centerY(to view: UIView, offset: CGFloat = 0.0) {
constrain(centerYAnchor, to: view.centerYAnchor, of: view, offset: offset)
}
func center(to view: UIView) {
guard superview == view.superview else { fatalError("Views do not belong in the same hierarchy") }
centerY(to: view)
centerX(to: view)
}
}
// MARK: - Superview Functions
extension UIView {
enum Edge: CaseIterable { case top, bottom, left, right, none }
func edgesToSuperview(excluding: Edge = .none, insets: UIEdgeInsets = .zero, usingSafeArea: Bool = false) {
guard let superview = superview else { fatalError("View does not have a superview") }
Edge.allCases.filter { $0 != excluding }.forEach {
switch $0 {
case .top: top(to: superview, offset: insets.top, usingSafeArea: usingSafeArea)
case .right: right(to: superview, offset: -insets.right, usingSafeArea: usingSafeArea)
case .bottom: bottom(to: superview, offset: -insets.bottom, usingSafeArea: usingSafeArea)
case .left: left(to: superview, offset: insets.left, usingSafeArea: usingSafeArea)
case .none: return
}
}
}
func bottomToSuperview(offset: CGFloat = 0.0, usingSafeArea: Bool = false) {
guard let superview = superview else { fatalError("View does not have a superview") }
bottom(to: superview, offset: offset, usingSafeArea: usingSafeArea)
}
func topToSuperview(offset: CGFloat = 0.0, usingSafeArea: Bool = false) {
guard let superview = superview else { fatalError("View does not have a superview") }
top(to: superview, offset: offset, usingSafeArea: usingSafeArea)
}
func rightToSuperview(offset: CGFloat = 0.0, usingSafeArea: Bool = false) {
guard let superview = superview else { fatalError("View does not have a superview") }
right(to: superview, offset: offset, usingSafeArea: usingSafeArea)
}
func leftToSuperview(offset: CGFloat = 0.0, usingSafeArea: Bool = false) {
guard let superview = superview else { fatalError("View does not have a superview") }
left(to: superview, offset: offset, usingSafeArea: usingSafeArea)
}
func centerXToSuperview(usingSafeArea: Bool = false) {
guard let superview = superview else { fatalError("View does not have a superview") }
centerX(to: superview)
}
func centerYToSuperview(usingSafeArea: Bool = false) {
guard let superview = superview else { fatalError("View does not have a superview") }
centerY(to: superview)
}
func centerToSuperview() {
guard let superview = superview else { fatalError("View does not have a superview") }
center(to: superview)
}
func widthToSuperview(usingSafeArea: Bool = false) {
guard let superview = superview else { fatalError("View does not have a superview") }
width(to: superview, usingSafeArea: usingSafeArea)
}
func heightToSuperview(usingSafeArea: Bool = false) {
guard let superview = superview else { fatalError("View does not have a superview") }
height(to: superview, usingSafeArea: usingSafeArea)
}
}
// MARK:- Base Functions
extension UIView {
func width(to view: UIView, usingSafeArea: Bool = false) {
translatesAutoresizingMaskIntoConstraints = false
constrain(widthAnchor, to: view.widthAnchor, of: view)
}
func height(to view: UIView, usingSafeArea: Bool = false) {
translatesAutoresizingMaskIntoConstraints = false
constrain(heightAnchor, to: view.heightAnchor, of: view)
}
func height(_ height: CGFloat) {
translatesAutoresizingMaskIntoConstraints = false
heightAnchor.constraint(equalToConstant: height).isActive = true
}
func width(_ width: CGFloat) {
translatesAutoresizingMaskIntoConstraints = false
widthAnchor.constraint(equalToConstant: width).isActive = true
}
func aspectRation(_ ratio: CGFloat) {
widthAnchor.constraint(equalTo: heightAnchor, multiplier: ratio).isActive = true
}
fileprivate func constrain(_ from: NSLayoutDimension, to: NSLayoutDimension, of view: UIView) {
// guard superview == view.superview else { fatalError("Views do not belong in the same hierarchy") }
translatesAutoresizingMaskIntoConstraints = false
from.constraint(equalTo: to).isActive = true
}
fileprivate func constrain(_ from: NSLayoutYAxisAnchor, to: NSLayoutYAxisAnchor?, of view: UIView?, offset: CGFloat = 0.0) {
// guard superview == view.superview else { fatalError("Views do not belong in the same hierarchy") }
translatesAutoresizingMaskIntoConstraints = false
guard let to = to else { return }
from.constraint(equalTo: to, constant: offset).isActive = true
}
fileprivate func constrain(_ from: NSLayoutXAxisAnchor, to: NSLayoutXAxisAnchor?, of view: UIView?, offset: CGFloat = 0.0) {
// guard superview == view.superview else { fatalError("Views do not belong in the same hierarchy") }
translatesAutoresizingMaskIntoConstraints = false
guard let to = to else { return }
from.constraint(equalTo: to, constant: offset).isActive = true
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment