Untitled
unknown
plain_text
2 years ago
11 kB
9
Indexable
public extension UIView { // MARK: - Enums enum Side { case top case bottom case leading case trailing } enum Dimension { case height case width } enum Center { case vertical case horizontal } // MARK: - Anchors @discardableResult func fillSuperviewWidth(distance: CGFloat = 0.0, priority: UILayoutPriority = .required) -> [NSLayoutConstraint] { return alignWithSuperview(sides: [.leading, .trailing], distance: distance, priority: priority) } @discardableResult func fillSuperviewHeight(distance: CGFloat = 0.0, priority: UILayoutPriority = .required) -> [NSLayoutConstraint] { return alignWithSuperview(sides: [.top, .bottom], distance: distance, priority: priority) } @discardableResult func fillSuperview(distance: CGFloat = 0.0, priority: UILayoutPriority = .required) -> [NSLayoutConstraint] { return alignWithSuperview(sides: [.leading, .trailing, .top, .bottom], distance: distance, priority: priority) } @discardableResult func alignWithSuperview( sides: [Side], distance: CGFloat = 0.0, priority: UILayoutPriority = .required, relation: NSLayoutConstraint.Relation = .equal ) -> [NSLayoutConstraint] { var constraints = [NSLayoutConstraint]() if let superview = self.superview { for side in sides { constraints.append(align(side, withSide: side, of: superview, distance: distance, priority: priority, relation: relation)) } } return constraints } @discardableResult func alignWithSuperview( _ side: Side, distance: CGFloat = 0.0, priority: UILayoutPriority = .required, relation: NSLayoutConstraint.Relation = .equal ) -> NSLayoutConstraint { if let constraint = alignWithSuperview(sides: [side], distance: distance, priority: priority, relation: relation).first { return constraint } return .init() } @discardableResult func fillSafeArea(distance: CGFloat = 0.0, priority: UILayoutPriority = .required) -> [NSLayoutConstraint] { return alignWithSafeArea(sides: [.leading, .trailing, .top, .bottom], distance: distance, priority: priority) } @discardableResult func alignWithSafeArea( sides: [Side], distance: CGFloat = 0.0, priority: UILayoutPriority = .required, relation: NSLayoutConstraint.Relation = .equal ) -> [NSLayoutConstraint] { var constraints = [NSLayoutConstraint]() if let safeArea = self.superview?.safeAreaLayoutGuide { for side in sides { constraints.append( align( side, withSide: side, target: safeArea, distance: distance, priority: priority, relation: relation ) ) } } return constraints } @discardableResult func alignWithSafeArea( _ side: Side, distance: CGFloat = 0.0, priority: UILayoutPriority = .required, relation: NSLayoutConstraint.Relation = .equal ) -> NSLayoutConstraint { if let constraint = alignWithSafeArea(sides: [side], distance: distance, priority: priority, relation: relation).first { return constraint } return .init() } @discardableResult func align( _ side: Side, withSide otherSide: Side, of view: UIView, distance: CGFloat = 0.0, priority: UILayoutPriority = .required, relation: NSLayoutConstraint.Relation = .equal ) -> NSLayoutConstraint { return align( side, withSide: otherSide, target: view, distance: distance, priority: priority, relation: relation ) } private func align( _ side: Side, withSide otherSide: Side, target: Any, distance: CGFloat = 0.0, priority: UILayoutPriority = .required, relation: NSLayoutConstraint.Relation = .equal ) -> NSLayoutConstraint { self.translatesAutoresizingMaskIntoConstraints = false var convertedDistance = distance if side == otherSide && (side == .trailing || side == .bottom) { convertedDistance = -distance } let constraint = NSLayoutConstraint( item: self, attribute: layoutAttribute(for: side), relatedBy: relation, toItem: target, attribute: layoutAttribute(for: otherSide), multiplier: 1.0, constant: convertedDistance ) constraint.priority = priority constraint.isActive = true return constraint } // MARK: - Dimension @discardableResult func pinHeight(_ constant: CGFloat, priority: UILayoutPriority = .required) -> NSLayoutConstraint { return pinDimension(.height, of: nil, constant: constant, priority: priority) } @discardableResult func pinWidth(_ constant: CGFloat, priority: UILayoutPriority = .required) -> NSLayoutConstraint { return pinDimension(.width, of: nil, constant: constant, priority: priority) } @discardableResult func pinHeight(to view: UIView, priority: UILayoutPriority = .required) -> NSLayoutConstraint { return pinDimension(.height, of: view, priority: priority) } @discardableResult func pinWidth(to view: UIView, priority: UILayoutPriority = .required) -> NSLayoutConstraint { return pinDimension(.width, of: view, priority: priority) } @discardableResult func pinSize(_ constant: CGFloat, priority: UILayoutPriority = .required) -> [NSLayoutConstraint] { return [pinHeight(constant, priority: priority), pinWidth(constant, priority: priority)] } @discardableResult func aspectRatio( for dimension: UIView.Dimension, ratio: CGFloat, priority: UILayoutPriority = .required ) -> NSLayoutConstraint { self.translatesAutoresizingMaskIntoConstraints = false let firstDimension: NSLayoutConstraint.Attribute let secondDimension: NSLayoutConstraint.Attribute switch dimension { case .height: firstDimension = .width secondDimension = .height case .width: firstDimension = .height secondDimension = .width } let constraint = NSLayoutConstraint( item: self, attribute: firstDimension, relatedBy: .equal, toItem: self, attribute: secondDimension, multiplier: ratio, constant: 0.0 ) constraint.priority = priority constraint.isActive = true return constraint } // MARK: - Center @discardableResult func pinCenterHorizontally(priority: UILayoutPriority = .required) -> NSLayoutConstraint { if let superview = self.superview { return pinCenterHorizontally(to: superview, priority: priority) } return .init() } @discardableResult func pinCenterVertically(priority: UILayoutPriority = .required) -> NSLayoutConstraint { if let superview = self.superview { return pinCenterVertically(to: superview, priority: priority) } return .init() } @discardableResult func pinCenterHorizontally(to view: UIView, priority: UILayoutPriority = .required) -> NSLayoutConstraint { return pinCenter(.horizontal, of: view, priority: priority) } @discardableResult func pinCenterVertically(to view: UIView, priority: UILayoutPriority = .required) -> NSLayoutConstraint { return pinCenter(.vertical, of: view, priority: priority) } @discardableResult func pinCenter(priority: UILayoutPriority = .required) -> [NSLayoutConstraint] { var constraints = [NSLayoutConstraint]() constraints.append(pinCenterVertically(priority: priority)) constraints.append(pinCenterHorizontally(priority: priority)) return constraints } private func pinDimension( _ dimension: Dimension, of target: UIView?, constant: CGFloat = 0.0, priority: UILayoutPriority = .required ) -> NSLayoutConstraint { return pinEqual(layoutAttribute(for: dimension), of: target, constant: constant, priority: priority) } private func pinCenter( _ center: Center, of target: UIView, constant: CGFloat = 0.0, priority: UILayoutPriority = .required ) -> NSLayoutConstraint { return pinEqual(layoutAttribute(for: center), of: target, constant: constant, priority: priority) } private func pinEqual( _ attribute: NSLayoutConstraint.Attribute, of target: UIView?, constant: CGFloat = 0.0, priority: UILayoutPriority = .required ) -> NSLayoutConstraint { self.translatesAutoresizingMaskIntoConstraints = false let constraint = NSLayoutConstraint( item: self, attribute: attribute, relatedBy: .equal, toItem: target, attribute: attribute, multiplier: 1.0, constant: constant ) constraint.priority = priority constraint.isActive = true return constraint } private func layoutAttribute(for side: Side) -> NSLayoutConstraint.Attribute { switch side { case .top: return .top case .bottom: return .bottom case .leading: return .leading case .trailing: return .trailing } } private func layoutAttribute(for dimension: Dimension) -> NSLayoutConstraint.Attribute { switch dimension { case .height: return .height case .width: return .width } } private func layoutAttribute(for center: Center) -> NSLayoutConstraint.Attribute { switch center { case .vertical: return .centerY case .horizontal: return .centerX } } }
Editor is loading...
Leave a Comment