Created
May 30, 2021 12:07
-
-
Save bernardonigbinde/04e3d0e3eb4b5774c785b1451e349142 to your computer and use it in GitHub Desktop.
UIView extension - Auto Layout Helper
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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