diff --git a/VDS.xcodeproj/project.pbxproj b/VDS.xcodeproj/project.pbxproj index addff05e..41fb8bb7 100644 --- a/VDS.xcodeproj/project.pbxproj +++ b/VDS.xcodeproj/project.pbxproj @@ -48,6 +48,7 @@ EA33623E2892EE950071C351 /* UIDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA33623D2892EE950071C351 /* UIDevice.swift */; }; EA3362402892EF6C0071C351 /* Label.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA33623F2892EF6B0071C351 /* Label.swift */; }; EA33624728931B050071C351 /* Initable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA33624628931B050071C351 /* Initable.swift */; }; + EA471F382A9545A700CE9E58 /* UILayoutGuide.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA471F372A9545A700CE9E58 /* UILayoutGuide.swift */; }; EA4DB18528CA967F00103EE3 /* SelectorGroupHandlerBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA4DB18428CA967F00103EE3 /* SelectorGroupHandlerBase.swift */; }; EA4DB2FD28D3D0CA00103EE3 /* AnyEquatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA4DB2FC28D3D0CA00103EE3 /* AnyEquatable.swift */; }; EA4DB30228DCBCA500103EE3 /* Badge.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA4DB30128DCBCA500103EE3 /* Badge.swift */; }; @@ -194,6 +195,7 @@ EA33623D2892EE950071C351 /* UIDevice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIDevice.swift; sourceTree = ""; }; EA33623F2892EF6B0071C351 /* Label.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Label.swift; sourceTree = ""; }; EA33624628931B050071C351 /* Initable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Initable.swift; sourceTree = ""; }; + EA471F372A9545A700CE9E58 /* UILayoutGuide.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UILayoutGuide.swift; sourceTree = ""; }; EA4DB18428CA967F00103EE3 /* SelectorGroupHandlerBase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectorGroupHandlerBase.swift; sourceTree = ""; }; EA4DB2FC28D3D0CA00103EE3 /* AnyEquatable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnyEquatable.swift; sourceTree = ""; }; EA4DB30128DCBCA500103EE3 /* Badge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Badge.swift; sourceTree = ""; }; @@ -467,6 +469,7 @@ EA3361A7288B23300071C351 /* UIColor.swift */, EA81410F2A127066004F60D2 /* UIColor+VDSColor.swift */, EA33623D2892EE950071C351 /* UIDevice.swift */, + EA471F372A9545A700CE9E58 /* UILayoutGuide.swift */, EAF7F0B6289C12A600B287F5 /* UITapGestureRecognizer.swift */, EA8E40902A7D3F6300934ED3 /* UIView+Accessibility.swift */, EAB5FED329267EB300998C17 /* UIView+NSLayoutConstraint.swift */, @@ -951,6 +954,7 @@ EA5F86D02A1F936100BC83E4 /* TabsContainer.swift in Sources */, EAF7F0B1289B177F00B287F5 /* ColorLabelAttribute.swift in Sources */, EAC9258F2911C9DE00091998 /* EntryField.swift in Sources */, + EA471F382A9545A700CE9E58 /* UILayoutGuide.swift in Sources */, EAB1D2EA28AE84AA00DAE764 /* UIControlPublisher.swift in Sources */, EAD068922A560B65002E3A2D /* LoaderViewController.swift in Sources */, EABFEB642A26473700C4C106 /* NSAttributedString.swift in Sources */, diff --git a/VDS/Extensions/UILayoutGuide.swift b/VDS/Extensions/UILayoutGuide.swift new file mode 100644 index 00000000..bd2a75a4 --- /dev/null +++ b/VDS/Extensions/UILayoutGuide.swift @@ -0,0 +1,464 @@ +// +// NSLayoutGuide.swift +// VDS +// +// Created by Matt Bruce on 8/22/23. +// + +import Foundation +import UIKit + + +//-------------------------------------------------- +// MARK: - Pinning +//-------------------------------------------------- +extension UILayoutGuide { + @discardableResult + /// Pins each to the all 4 anchor points to a view. + /// - Parameters: + /// - view: View that you will be pinned within. + /// - edges: Insets for each side. + /// - Returns: Yourself. + public func pin(_ view: UIView, with edges: UIEdgeInsets = UIEdgeInsets.zero) -> Self { + pinLeading(view.leadingAnchor, edges.left) + pinTrailing(view.trailingAnchor, edges.right) + pinTop(view.topAnchor, edges.top) + pinBottom(view.bottomAnchor, edges.bottom) + return self + } + + @discardableResult + + /// Pins each to the all 4 anchor points to the view you are set within. + /// - Parameter edges: Insets for each side. + /// - Returns: Yourself. + public func pinToOwningView(_ edges: UIEdgeInsets = UIEdgeInsets.zero) -> Self { + if let owningView { + pin(owningView, with: edges) + } + return self + } +} + +//-------------------------------------------------- +// MARK: - HeightAnchor +//-------------------------------------------------- +extension UILayoutGuide { + + @discardableResult + /// Adds a heightAnchor. + /// - Parameter constant: Constant size. + /// - Returns: Yourself. + public func height(_ constant: CGFloat) -> Self { + height(constant: constant) + return self + } + + @discardableResult + /// Adds a heightAnchor where the height constant passed in using a greaterThanOrEqualTo Constraint. + /// - Parameter constant: Constant size. + /// - Returns: Yourself. + public func heightGreaterThanEqualTo(_ constant: CGFloat) -> Self { + heightGreaterThanEqualTo(constant: constant) + return self + } + + @discardableResult + /// Adds a heightAnchor where the height constant passed in using a lessThanOrEqualTo Constraint. + /// - Parameter constant: Constant size. + /// - Returns: Yourself. + public func heightLessThanEqualTo(_ constant: CGFloat) -> Self { + heightLessThanEqualTo(constant: constant) + return self + } + + @discardableResult + /// Adds a heightAnchor for the constant passed into the method. + /// - Parameter constant: Constant size. + /// - Returns: The Constraint that was created. + public func height(constant: CGFloat) -> NSLayoutConstraint { + heightAnchor.constraint(equalToConstant: constant).activate() + } + + @discardableResult + /// Adds a heightAnchor where the constant passed in using a greaterThanOrEqualTo Constraint. + /// - Parameter constant: Constant size. + /// - Returns: The Constraint that was created. + public func heightGreaterThanEqualTo(constant: CGFloat) -> NSLayoutConstraint { + heightAnchor.constraint(greaterThanOrEqualToConstant: constant).activate() + } + + @discardableResult + /// Adds a heightAnchor where the constant passed in using a lessThanOrEqualTo Constraint. + /// - Parameter constant: Constant size. + /// - Returns: The Constraint that was created. + public func heightLessThanEqualTo(constant: CGFloat) -> NSLayoutConstraint { + heightAnchor.constraint(lessThanOrEqualToConstant: constant).activate() + } + +} + +//-------------------------------------------------- +// MARK: - WidthAnchor +//-------------------------------------------------- +extension UILayoutGuide { + + @discardableResult + /// Adds a widthAnchor. + /// - Parameter constant: Width Constant size. + /// - Returns: Yourself. + public func width(_ constant: CGFloat) -> Self { + width(constant: constant) + return self + } + + @discardableResult + /// Adds a widthAnchor where the constant passed in using a greaterThanOrEqualTo Constraint. + /// - Parameter constant: Constant size. + /// - Returns: Yourself. + public func widthGreaterThanEqualTo(_ constant: CGFloat) -> Self { + widthGreaterThanEqualTo(constant: constant) + return self + } + + @discardableResult + /// Adds a widthAnchor where the constant passed in using a lessThanOrEqualTo Constraint. + /// - Parameter constant: Constant size. + /// - Returns: Yourself. + public func widthLessThanEqualTo(_ constant: CGFloat) -> Self { + widthLessThanEqualTo(constant: constant) + return self + } + + @discardableResult + /// Adds a widthAnchor for the constant passed into the method. + /// - Parameter constant: Constant size. + /// - Returns: The Constraint that was created. + public func width(constant: CGFloat) -> NSLayoutConstraint { + widthAnchor.constraint(equalToConstant: constant).activate() + } + + @discardableResult + /// Adds a widthAnchor with the constant passed in using a greaterThanOrEqualTo Constraint. + /// - Parameter constant: Constant size. + /// - Returns: The Constraint that was created. + public func widthGreaterThanEqualTo(constant: CGFloat) -> NSLayoutConstraint { + widthAnchor.constraint(greaterThanOrEqualToConstant: constant).activate() + } + + @discardableResult + /// Adds a widthAnchor with the constant passed in using a lessThanOrEqualTo Constraint. + /// - Parameter constant: Constant size. + /// - Returns: The Constraint that was created. + public func widthLessThanEqualTo(constant: CGFloat) -> NSLayoutConstraint { + widthAnchor.constraint(lessThanOrEqualToConstant: constant).activate() + } +} + +//-------------------------------------------------- +// MARK: - TopAnchor +//-------------------------------------------------- +extension UILayoutGuide { + + @discardableResult + /// Adds a topAnchor. + /// - Parameter constant: Constant size. + /// - Returns: Yourself. + public func pinTop(_ constant: CGFloat = 0.0, _ priority: UILayoutPriority = .required) -> Self { + return pinTop(nil, constant, priority) + } + + @discardableResult + /// Adds a topAnchor to a specific YAxisAnchor. + /// - Parameter anchor:The anchor in which to attach the topAnchor + /// - constant: Constant size. + /// - Returns: Yourself. + public func pinTop(_ anchor: NSLayoutYAxisAnchor? = nil, _ constant: CGFloat = 0.0, _ priority: UILayoutPriority = .required) -> Self { + pinTop(anchor: anchor, constant: constant, priority: priority) + return self + } + + @discardableResult + /// Adds a topAnchor to a specific YAxisAnchor passed in using a lessThanOrEqualTo Constraint + /// - Parameter anchor:The anchor in which to attach the topAnchor + /// - constant: Constant size. + /// - Returns: Yourself. + public func pinTopLessThanOrEqualTo(_ anchor: NSLayoutYAxisAnchor? = nil, _ constant: CGFloat = 0.0, _ priority: UILayoutPriority = .required) -> Self { + pinTopLessThanOrEqualTo(anchor: anchor, constant: constant, priority: priority) + return self + } + + @discardableResult + /// Adds a topAnchor to a specific YAxisAnchor passed in using a greaterThanOrEqualTo Constraint + /// - Parameter anchor:The anchor in which to attach the topAnchor + /// - constant: Constant size. + /// - Returns: Yourself. + public func pinTopGreaterThanOrEqualTo(_ anchor: NSLayoutYAxisAnchor? = nil, _ constant: CGFloat = 0.0, _ priority: UILayoutPriority = .required) -> Self { + pinTopGreaterThanOrEqualTo(anchor: anchor, constant: constant, priority: priority) + return self + } + + @discardableResult + /// Adds a topAnchor for the constant passed into the method. + /// - Parameter anchor:The anchor in which to attach the topAnchor + /// - constant: Constant size. + /// - Returns: The Constraint that was created. + public func pinTop(anchor: NSLayoutYAxisAnchor?, constant: CGFloat = 0.0, priority: UILayoutPriority = .required) -> NSLayoutConstraint? { + let found: NSLayoutYAxisAnchor? = anchor ?? owningView?.topAnchor + guard let found else { return nil } + return topAnchor.constraint(equalTo: found, constant: constant).with { $0.priority = priority; $0.isActive = true } + } + + @discardableResult + /// Adds a topAnchor with the constant passed in using a lessThanOrEqualTo Constraint. + /// - Parameter anchor:The anchor in which to attach the topAnchor + /// - constant: Constant size. + /// - Returns: The Constraint that was created. + public func pinTopLessThanOrEqualTo(anchor: NSLayoutYAxisAnchor?, constant: CGFloat = 0.0, priority: UILayoutPriority = .required) -> NSLayoutConstraint? { + let found: NSLayoutYAxisAnchor? = anchor ?? owningView?.topAnchor + guard let found else { return nil } + return topAnchor.constraint(lessThanOrEqualTo: found, constant: constant).with { $0.priority = priority; $0.isActive = true } + } + + @discardableResult + /// Adds a topAnchor with the constant passed in using a greaterThanOrEqualTo Constraint. + /// - Parameter anchor:The anchor in which to attach the topAnchor + /// - constant: Constant size. + /// - Returns: The Constraint that was created. + public func pinTopGreaterThanOrEqualTo(anchor: NSLayoutYAxisAnchor?, constant: CGFloat = 0.0, priority: UILayoutPriority = .required) -> NSLayoutConstraint? { + let found: NSLayoutYAxisAnchor? = anchor ?? owningView?.topAnchor + guard let found else { return nil } + return topAnchor.constraint(greaterThanOrEqualTo: found, constant: constant).with { $0.priority = priority; $0.isActive = true } + } + +} + +//-------------------------------------------------- +// MARK: - BottomAnchor +//-------------------------------------------------- +extension UILayoutGuide { + @discardableResult + /// Adds a bottomAnchor. + /// - Parameter constant: Constant size. + /// - Returns: Yourself. + public func pinBottom(_ constant: CGFloat = 0.0, _ priority: UILayoutPriority = .required) -> Self { + return pinBottom(nil, constant, priority) + } + + @discardableResult + /// Adds a bottomAnchor to a specific YAxisAnchor. + /// - Parameter anchor:The anchor in which to attach the bottomAnchor + /// - constant: Constant size. + /// - Returns: Yourself. + public func pinBottom(_ anchor: NSLayoutYAxisAnchor? = nil, _ constant: CGFloat = 0.0, _ priority: UILayoutPriority = .required) -> Self { + pinBottom(anchor: anchor, constant: constant, priority: priority) + return self + } + + @discardableResult + /// Adds a bottomAnchor to a specific YAxisAnchor passed in using a lessThanOrEqualTo Constraint + /// - Parameter anchor:The anchor in which to attach the bottomAnchor + /// - constant: Constant size. + /// - Returns: Yourself. + public func pinBottomLessThanOrEqualTo(_ anchor: NSLayoutYAxisAnchor? = nil, _ constant: CGFloat = 0.0, _ priority: UILayoutPriority = .required) -> Self { + pinBottomLessThanOrEqualTo(anchor: anchor, constant: constant, priority: priority) + return self + } + + @discardableResult + /// Adds a bottomAnchor to a specific YAxisAnchor passed in using a greaterThanOrEqualTo Constraint + /// - Parameter anchor:The anchor in which to attach the bottomAnchor + /// - constant: Constant size. + /// - Returns: Yourself. + public func pinBottomGreaterThanOrEqualTo(_ anchor: NSLayoutYAxisAnchor? = nil, _ constant: CGFloat = 0.0, _ priority: UILayoutPriority = .required) -> Self { + pinBottomGreaterThanOrEqualTo(anchor: anchor, constant: constant, priority: priority) + return self + } + + @discardableResult + /// Adds a bottomAnchor for the constant passed into the method. + /// - Parameter anchor:The anchor in which to attach the bottomAnchor + /// - constant: Constant size. + /// - Returns: The Constraint that was created. + public func pinBottom(anchor: NSLayoutYAxisAnchor?, constant: CGFloat = 0.0, priority: UILayoutPriority = .required) -> NSLayoutConstraint? { + let found: NSLayoutYAxisAnchor? = anchor ?? owningView?.bottomAnchor + guard let found else { return nil } + return bottomAnchor.constraint(equalTo: found, constant: -constant).with { $0.priority = priority; $0.isActive = true } + } + + @discardableResult + /// Adds a bottomAnchor with the constant passed in using a lessThanOrEqualTo Constraint. + /// - Parameter anchor:The anchor in which to attach the bottomAnchor + /// - constant: Constant size. + /// - Returns: The Constraint that was created. + public func pinBottomLessThanOrEqualTo(anchor: NSLayoutYAxisAnchor?, constant: CGFloat = 0.0, priority: UILayoutPriority = .required) -> NSLayoutConstraint? { + let found: NSLayoutYAxisAnchor? = anchor ?? owningView?.bottomAnchor + guard let found else { return nil } + return bottomAnchor.constraint(lessThanOrEqualTo: found, constant: -constant).with { $0.priority = priority; $0.isActive = true } + } + + @discardableResult + /// Adds a bottomAnchor with the constant passed in using a greaterThanOrEqualTo Constraint. + /// - Parameter anchor:The anchor in which to attach the bottomAnchor + /// - constant: Constant size. + /// - Returns: The Constraint that was created. + public func pinBottomGreaterThanOrEqualTo(anchor: NSLayoutYAxisAnchor?, constant: CGFloat = 0.0, priority: UILayoutPriority = .required) -> NSLayoutConstraint? { + let found: NSLayoutYAxisAnchor? = anchor ?? owningView?.bottomAnchor + guard let found else { return nil } + return bottomAnchor.constraint(greaterThanOrEqualTo: found, constant: -constant).with { $0.priority = priority; $0.isActive = true } + } +} + +//-------------------------------------------------- +// MARK: - LeadingAnchor +//-------------------------------------------------- +extension UILayoutGuide { + + @discardableResult + /// Adds a leadingAnchor. + /// - Parameter constant: Constant size. + /// - Returns: Yourself. + public func pinLeading(_ constant: CGFloat = 0.0, _ priority: UILayoutPriority = .required) -> Self { + return pinLeading(nil, constant, priority) + } + + @discardableResult + /// Adds a leadingAnchor to a specific XAxisAnchor. + /// - Parameter anchor:The anchor in which to attach the leadingAnchor. + /// - constant: Constant size. + /// - Returns: Yourself. + public func pinLeading(_ anchor: NSLayoutXAxisAnchor? = nil, _ constant: CGFloat = 0.0, _ priority: UILayoutPriority = .required) -> Self { + pinLeading(anchor: anchor, constant: constant, priority: priority) + return self + } + + @discardableResult + /// Adds a leadingAnchor to a specific XAxisAnchor passed in using a greaterThanOrEqualTo Constraint + /// - Parameter anchor:The anchor in which to attach the leadingAnchor + /// - constant: Constant size. + /// - Returns: Yourself. + public func pinLeadingLessThanOrEqualTo(_ anchor: NSLayoutXAxisAnchor? = nil, _ constant: CGFloat = 0.0, _ priority: UILayoutPriority = .required) -> Self { + pinLeadingLessThanOrEqualTo(anchor: anchor, constant: constant, priority: priority) + return self + } + + @discardableResult + /// Adds a leadingAnchor to a specific XAxisAnchor passed in using a greaterThanOrEqualTo Constraint + /// - Parameter anchor:The anchor in which to attach the leadingAnchor + /// - constant: Constant size. + /// - Returns: Yourself. + public func pinLeadingGreaterThanOrEqualTo(_ anchor: NSLayoutXAxisAnchor? = nil, _ constant: CGFloat = 0.0, _ priority: UILayoutPriority = .required) -> Self { + pinLeadingGreaterThanOrEqualTo(anchor: anchor, constant: constant, priority: priority) + return self + } + + @discardableResult + /// Adds a leadingAnchor for the constant passed into the method. + /// - Parameter anchor:The anchor in which to attach the leadingAnchor + /// - constant: Constant size. + /// - Returns: The Constraint that was created. + public func pinLeading(anchor: NSLayoutXAxisAnchor?, constant: CGFloat = 0.0, priority: UILayoutPriority = .required) -> NSLayoutConstraint? { + let found: NSLayoutXAxisAnchor? = anchor ?? owningView?.leadingAnchor + guard let found else { return nil } + return leadingAnchor.constraint(equalTo: found, constant: constant).with { $0.priority = priority; $0.isActive = true } + } + + @discardableResult + /// Adds a leadingAnchor with the constant passed in using a lessThanOrEqualTo Constraint. + /// - Parameter anchor:The anchor in which to attach the leadingAnchor + /// - constant: Constant size. + /// - Returns: The Constraint that was created. + public func pinLeadingLessThanOrEqualTo(anchor: NSLayoutXAxisAnchor?, constant: CGFloat = 0.0, priority: UILayoutPriority = .required) -> NSLayoutConstraint? { + let found: NSLayoutXAxisAnchor? = anchor ?? owningView?.leadingAnchor + guard let found else { return nil } + return leadingAnchor.constraint(lessThanOrEqualTo: found, constant: constant).with { $0.priority = priority; $0.isActive = true } + } + + @discardableResult + /// Adds a leadingAnchor with the constant passed in using a greaterThanOrEqualTo Constraint. + /// - Parameter anchor:The anchor in which to attach the leadingAnchor + /// - constant: Constant size. + /// - Returns: The Constraint that was created. + public func pinLeadingGreaterThanOrEqualTo(anchor: NSLayoutXAxisAnchor?, constant: CGFloat = 0.0, priority: UILayoutPriority = .required) -> NSLayoutConstraint? { + let found: NSLayoutXAxisAnchor? = anchor ?? owningView?.leadingAnchor + guard let found else { return nil } + return leadingAnchor.constraint(greaterThanOrEqualTo: found, constant: constant).with { $0.priority = priority; $0.isActive = true } + } +} + +//-------------------------------------------------- +// MARK: - TrailingAnchor +//-------------------------------------------------- +extension UILayoutGuide { + + @discardableResult + /// Adds a trailingAnchor. + /// - Parameter constant: Constant size. + /// - Returns: Yourself. + public func pinTrailing(_ constant: CGFloat = 0.0, _ priority: UILayoutPriority = .required) -> Self { + pinTrailing(nil, constant) + } + + @discardableResult + /// Adds a trailingAnchor to a specific XAxisAnchor. + /// - Parameter anchor:The anchor in which to attach the trailingAnchor. + /// - constant: Constant size. + /// - Returns: Yourself. + public func pinTrailing(_ anchor: NSLayoutXAxisAnchor? = nil, _ constant: CGFloat = 0.0, _ priority: UILayoutPriority = .required) -> Self { + pinTrailing(anchor: anchor, constant: constant) + return self + } + + @discardableResult + /// Adds a trailingAnchor to a specific XAxisAnchor passed in using a lessThanOrEqualTo Constraint + /// - Parameter anchor:The anchor in which to attach the trailingAnchor + /// - constant: Constant size. + /// - Returns: Yourself. + public func pinTrailingLessThanOrEqualTo(_ anchor: NSLayoutXAxisAnchor? = nil, _ constant: CGFloat = 0.0, _ priority: UILayoutPriority = .required) -> Self { + pinTrailingLessThanOrEqualTo(anchor: anchor, constant: constant) + return self + } + + @discardableResult + /// Adds a trailingAnchor to a specific XAxisAnchor passed in using a greaterThanOrEqualTo Constraint + /// - Parameter anchor:The anchor in which to attach the trailingAnchor + /// - constant: Constant size. + /// - Returns: Yourself. + public func pinTrailingGreaterThanOrEqualTo(_ anchor: NSLayoutXAxisAnchor? = nil, _ constant: CGFloat = 0.0) -> Self { + pinTrailingGreaterThanOrEqualTo(anchor: anchor, constant: constant) + return self + } + + @discardableResult + /// Adds a trailingAnchor for the constant passed into the method. + /// - Parameter anchor:The anchor in which to attach the trailingAnchor + /// - constant: Constant size. + /// - Returns: The Constraint that was created. + public func pinTrailing(anchor: NSLayoutXAxisAnchor?, constant: CGFloat = 0.0, priority: UILayoutPriority = .required) -> NSLayoutConstraint? { + let found: NSLayoutXAxisAnchor? = anchor ?? owningView?.trailingAnchor + guard let found else { return nil } + return trailingAnchor.constraint(equalTo: found, constant: -constant).with { $0.priority = priority; $0.isActive = true } + } + + @discardableResult + /// Adds a trailingAnchor with the constant passed in using a lessThanOrEqualTo Constraint. + /// - Parameter anchor:The anchor in which to attach the trailingAnchor + /// - constant: Constant size. + /// - Returns: The Constraint that was created. + public func pinTrailingLessThanOrEqualTo(anchor: NSLayoutXAxisAnchor?, constant: CGFloat = 0.0, priority: UILayoutPriority = .required) -> NSLayoutConstraint? { + let found: NSLayoutXAxisAnchor? = anchor ?? owningView?.trailingAnchor + guard let found else { return nil } + return trailingAnchor.constraint(lessThanOrEqualTo: found, constant: -constant).with { $0.priority = priority; $0.isActive = true } + } + + @discardableResult + /// Adds a trailingAnchor with the constant passed in using a greaterThanOrEqualTo Constraint. + /// - Parameter anchor:The anchor in which to attach the trailingAnchor + /// - constant: Constant size. + /// - Returns: The Constraint that was created. + public func pinTrailingGreaterThanOrEqualTo(anchor: NSLayoutXAxisAnchor?, constant: CGFloat = 0.0, priority: UILayoutPriority = .required) -> NSLayoutConstraint? { + let found: NSLayoutXAxisAnchor? = anchor ?? owningView?.trailingAnchor + guard let found else { return nil } + return trailingAnchor.constraint(greaterThanOrEqualTo: found, constant: -constant).with { $0.priority = priority; $0.isActive = true } + } +}