652 lines
24 KiB
Swift
652 lines
24 KiB
Swift
//
|
|
// UIView.swift
|
|
// VDS
|
|
//
|
|
// Created by Matt Bruce on 11/17/22.
|
|
//
|
|
|
|
import Foundation
|
|
import UIKit
|
|
import VDSFormControlsTokens
|
|
|
|
extension UIView {
|
|
public enum ConstraintIdentifier: CustomStringConvertible {
|
|
case leading, trailing, top, bottom, height, width
|
|
case custom(String)
|
|
|
|
public var description: String {
|
|
switch self {
|
|
case .leading: return "leading"
|
|
case .trailing: return "trailing"
|
|
case .top: return "top"
|
|
case .bottom: return "bottom"
|
|
case .height: return "height"
|
|
case .width: return "width"
|
|
case .custom(let identifier): return identifier
|
|
}
|
|
}
|
|
}
|
|
|
|
public enum ConstraintType {
|
|
case equal, lessThanOrEqual, greaterThanOrEqual
|
|
}
|
|
|
|
public var _topConstraint: NSLayoutConstraint? { constraint(with: .top)}
|
|
public var _leadingConstraint: NSLayoutConstraint? { constraint(with: .leading)}
|
|
public var _trailingConstraint: NSLayoutConstraint? { constraint(with: .trailing)}
|
|
public var _bottomConstraint: NSLayoutConstraint? { constraint(with: .bottom)}
|
|
public var _widthConstraint: NSLayoutConstraint? { constraint(with: .width)}
|
|
public var _heightConstraint: NSLayoutConstraint? { constraint(with: .height)}
|
|
|
|
public func constraint(with identifier: ConstraintIdentifier) -> NSLayoutConstraint? {
|
|
return constraint(with: identifier.description)
|
|
}
|
|
|
|
public func constraint(with identifier: String) -> NSLayoutConstraint? {
|
|
return constraints.first { $0.identifier == identifier }
|
|
}
|
|
|
|
public func removeConstraint(edges: [UIRectEdge]) {
|
|
let topConstraint: NSLayoutConstraint? = constraint(with: .top)
|
|
let leadingConstraint: NSLayoutConstraint? = constraint(with: .leading)
|
|
let trailingConstraint: NSLayoutConstraint? = constraint(with: .trailing)
|
|
let bottomConstraint: NSLayoutConstraint? = constraint(with: .bottom)
|
|
|
|
edges.forEach { edge in
|
|
switch edge {
|
|
case .all:
|
|
if let leadingConstraint {
|
|
removeConstraint(leadingConstraint)
|
|
}
|
|
if let trailingConstraint {
|
|
removeConstraint(trailingConstraint)
|
|
}
|
|
if let topConstraint {
|
|
removeConstraint(topConstraint)
|
|
}
|
|
if let bottomConstraint {
|
|
removeConstraint(bottomConstraint)
|
|
}
|
|
case .left:
|
|
if let leadingConstraint {
|
|
removeConstraint(leadingConstraint)
|
|
}
|
|
case .right:
|
|
if let trailingConstraint {
|
|
removeConstraint(trailingConstraint)
|
|
}
|
|
case .top:
|
|
if let topConstraint {
|
|
removeConstraint(topConstraint)
|
|
}
|
|
case .bottom:
|
|
if let bottomConstraint {
|
|
removeConstraint(bottomConstraint)
|
|
}
|
|
default:
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------
|
|
// MARK: - Pinning
|
|
//--------------------------------------------------
|
|
extension UIView {
|
|
public func pin(_ view: UIView, with edges: UIEdgeInsets = UIEdgeInsets.zero) {
|
|
leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: edges.left, identifier: ConstraintIdentifier.leading.description).isActive = true
|
|
trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -edges.right, identifier: ConstraintIdentifier.trailing.description).isActive = true
|
|
topAnchor.constraint(equalTo: view.topAnchor, constant: edges.top, identifier: ConstraintIdentifier.top.description).isActive = true
|
|
bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -edges.bottom, identifier: ConstraintIdentifier.bottom.description).isActive = true
|
|
}
|
|
|
|
public func pinToSuperView(_ edges: UIEdgeInsets = UIEdgeInsets.zero) {
|
|
if let superview {
|
|
pin(superview, with: edges)
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------
|
|
// MARK: - HeightAnchor
|
|
//--------------------------------------------------
|
|
extension UIView {
|
|
|
|
@discardableResult
|
|
public func height(_ constant: CGFloat, type: ConstraintType = .equal) -> Self {
|
|
switch type {
|
|
case .equal:
|
|
height(constant)
|
|
|
|
case .lessThanOrEqual:
|
|
heightLessThanEqualTo(constant)
|
|
|
|
case .greaterThanOrEqual:
|
|
heightGreaterThanEqualTo(constant)
|
|
}
|
|
return self
|
|
}
|
|
|
|
@discardableResult
|
|
public func height(_ constant: CGFloat) -> Self {
|
|
heightAnchor.constraint(equalToConstant: constant, identifier: ConstraintIdentifier.height.description).isActive = true
|
|
return self
|
|
}
|
|
|
|
@discardableResult
|
|
public func heightGreaterThanEqualTo(_ constant: CGFloat) -> Self {
|
|
heightAnchor.constraint(greaterThanOrEqualToConstant: constant, identifier: ConstraintIdentifier.height.description).isActive = true
|
|
return self
|
|
}
|
|
|
|
@discardableResult
|
|
public func heightLessThanEqualTo(_ constant: CGFloat) -> Self {
|
|
heightAnchor.constraint(lessThanOrEqualToConstant: constant, identifier: ConstraintIdentifier.height.description).isActive = true
|
|
return self
|
|
}
|
|
|
|
}
|
|
|
|
//--------------------------------------------------
|
|
// MARK: - WidthAnchor
|
|
//--------------------------------------------------
|
|
extension UIView {
|
|
|
|
@discardableResult
|
|
public func width(_ constant: CGFloat, type: ConstraintType = .equal) -> Self {
|
|
switch type {
|
|
case .equal:
|
|
width(constant)
|
|
|
|
case .lessThanOrEqual:
|
|
widthLessThanEqualTo(constant)
|
|
|
|
case .greaterThanOrEqual:
|
|
widthGreaterThanEqualTo(constant)
|
|
}
|
|
return self
|
|
}
|
|
|
|
@discardableResult
|
|
public func width(_ constant: CGFloat) -> Self {
|
|
widthAnchor.constraint(equalToConstant: constant, identifier: ConstraintIdentifier.width.description).isActive = true
|
|
return self
|
|
}
|
|
|
|
@discardableResult
|
|
public func widthGreaterThanEqualTo(_ constant: CGFloat) -> Self {
|
|
widthAnchor.constraint(greaterThanOrEqualToConstant: constant, identifier: ConstraintIdentifier.width.description).isActive = true
|
|
return self
|
|
}
|
|
|
|
@discardableResult
|
|
public func widthLessThanEqualTo(_ constant: CGFloat) -> Self {
|
|
widthAnchor.constraint(lessThanOrEqualToConstant: constant, identifier: ConstraintIdentifier.width.description).isActive = true
|
|
return self
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------
|
|
// MARK: - TopAnchor
|
|
//--------------------------------------------------
|
|
extension UIView {
|
|
|
|
@discardableResult
|
|
public func pinTop(_ anchor: NSLayoutYAxisAnchor? = nil, _ constant: CGFloat = 0.0, _ type: ConstraintType = .equal) -> Self {
|
|
switch type {
|
|
case .equal:
|
|
pinTop(anchor, constant)
|
|
|
|
case .lessThanOrEqual:
|
|
pinTopLessThanOrEqualTo(anchor, constant)
|
|
|
|
case .greaterThanOrEqual:
|
|
pinTopGreaterThanOrEqualTo(anchor, constant)
|
|
}
|
|
return self
|
|
}
|
|
|
|
@discardableResult
|
|
public func pinTop(_ constant: CGFloat = 0.0) -> Self {
|
|
return pinTop(nil, constant)
|
|
}
|
|
|
|
@discardableResult
|
|
public func pinTop(_ anchor: NSLayoutYAxisAnchor? = nil, _ constant: CGFloat = 0.0) -> Self {
|
|
let found: NSLayoutYAxisAnchor? = anchor ?? superview?.topAnchor
|
|
if let found {
|
|
topAnchor.constraint(equalTo: found, constant: constant, identifier: ConstraintIdentifier.top.description).isActive = true
|
|
}
|
|
return self
|
|
}
|
|
|
|
@discardableResult
|
|
public func pinTopLessThanOrEqualTo(_ anchor: NSLayoutYAxisAnchor? = nil, _ constant: CGFloat = 0.0) -> Self {
|
|
let found: NSLayoutYAxisAnchor? = anchor ?? superview?.topAnchor
|
|
if let found {
|
|
topAnchor.constraint(lessThanOrEqualTo: found, constant: constant, identifier: ConstraintIdentifier.top.description).isActive = true
|
|
}
|
|
return self
|
|
}
|
|
|
|
@discardableResult
|
|
public func pinTopGreaterThanOrEqualTo(_ anchor: NSLayoutYAxisAnchor? = nil, _ constant: CGFloat = 0.0) -> Self {
|
|
let found: NSLayoutYAxisAnchor? = anchor ?? superview?.topAnchor
|
|
if let found {
|
|
topAnchor.constraint(greaterThanOrEqualTo: found, constant: constant, identifier: ConstraintIdentifier.top.description).isActive = true
|
|
}
|
|
return self
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------
|
|
// MARK: - BottomAnchor
|
|
//--------------------------------------------------
|
|
extension UIView {
|
|
@discardableResult
|
|
public func pinBottom(_ anchor: NSLayoutYAxisAnchor? = nil, _ constant: CGFloat = 0.0, _ type: ConstraintType = .equal) -> Self {
|
|
switch type {
|
|
case .equal:
|
|
pinBottom(anchor, constant)
|
|
|
|
case .lessThanOrEqual:
|
|
pinBottomLessThanOrEqualTo(anchor, constant)
|
|
|
|
case .greaterThanOrEqual:
|
|
pinBottomGreaterThanOrEqualTo(anchor, constant)
|
|
}
|
|
return self
|
|
}
|
|
|
|
@discardableResult
|
|
public func pinBottom(_ constant: CGFloat = 0.0) -> Self {
|
|
return pinBottom(nil, constant)
|
|
}
|
|
|
|
@discardableResult
|
|
public func pinBottom(_ anchor: NSLayoutYAxisAnchor? = nil, _ constant: CGFloat = 0.0) -> Self {
|
|
let found: NSLayoutYAxisAnchor? = anchor ?? superview?.bottomAnchor
|
|
if let found {
|
|
bottomAnchor.constraint(equalTo: found, constant: -constant, identifier: ConstraintIdentifier.bottom.description).isActive = true
|
|
}
|
|
return self
|
|
}
|
|
|
|
@discardableResult
|
|
public func pinBottomLessThanOrEqualTo(_ anchor: NSLayoutYAxisAnchor? = nil, _ constant: CGFloat = 0.0) -> Self {
|
|
let found: NSLayoutYAxisAnchor? = anchor ?? superview?.bottomAnchor
|
|
if let found {
|
|
bottomAnchor.constraint(lessThanOrEqualTo: found, constant: -constant, identifier: ConstraintIdentifier.bottom.description).isActive = true
|
|
}
|
|
return self
|
|
}
|
|
|
|
@discardableResult
|
|
public func pinBottomGreaterThanOrEqualTo(_ anchor: NSLayoutYAxisAnchor? = nil, _ constant: CGFloat = 0.0) -> Self {
|
|
let found: NSLayoutYAxisAnchor? = anchor ?? superview?.bottomAnchor
|
|
if let found {
|
|
bottomAnchor.constraint(greaterThanOrEqualTo: found, constant: -constant, identifier: ConstraintIdentifier.bottom.description).isActive = true
|
|
}
|
|
return self
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------
|
|
// MARK: - LeadingAnchor
|
|
//--------------------------------------------------
|
|
extension UIView {
|
|
@discardableResult
|
|
public func pinLeading(_ anchor: NSLayoutXAxisAnchor? = nil, _ constant: CGFloat = 0.0, _ type: ConstraintType = .equal) -> Self {
|
|
switch type {
|
|
case .equal:
|
|
pinLeading(anchor, constant)
|
|
|
|
case .lessThanOrEqual:
|
|
pinLeadingLessThanOrEqualTo(anchor, constant)
|
|
|
|
case .greaterThanOrEqual:
|
|
pinLeadingGreaterThanOrEqualTo(anchor, constant)
|
|
}
|
|
return self
|
|
}
|
|
|
|
@discardableResult
|
|
public func pinLeading(_ constant: CGFloat = 0.0) -> Self {
|
|
return pinLeading(nil, constant)
|
|
}
|
|
|
|
@discardableResult
|
|
public func pinLeading(_ anchor: NSLayoutXAxisAnchor? = nil, _ constant: CGFloat = 0.0) -> Self {
|
|
let found: NSLayoutXAxisAnchor? = anchor ?? superview?.leadingAnchor
|
|
if let found {
|
|
leadingAnchor.constraint(equalTo: found, constant: constant, identifier: ConstraintIdentifier.leading.description).isActive = true
|
|
}
|
|
return self
|
|
}
|
|
|
|
@discardableResult
|
|
public func pinLeadingLessThanOrEqualTo(_ anchor: NSLayoutXAxisAnchor? = nil, _ constant: CGFloat = 0.0) -> Self {
|
|
let found: NSLayoutXAxisAnchor? = anchor ?? superview?.leadingAnchor
|
|
if let found {
|
|
leadingAnchor.constraint(lessThanOrEqualTo: found, constant: constant, identifier: ConstraintIdentifier.leading.description).isActive = true
|
|
}
|
|
return self
|
|
}
|
|
|
|
@discardableResult
|
|
public func pinLeadingGreaterThanOrEqualTo(_ anchor: NSLayoutXAxisAnchor? = nil, _ constant: CGFloat = 0.0) -> Self {
|
|
let found: NSLayoutXAxisAnchor? = anchor ?? superview?.leadingAnchor
|
|
if let found {
|
|
leadingAnchor.constraint(greaterThanOrEqualTo: found, constant: constant, identifier: ConstraintIdentifier.leading.description).isActive = true
|
|
}
|
|
return self
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------
|
|
// MARK: - TrailingAnchor
|
|
//--------------------------------------------------
|
|
extension UIView {
|
|
|
|
@discardableResult
|
|
public func pinTrailing(_ anchor: NSLayoutXAxisAnchor? = nil, _ constant: CGFloat = 0.0, _ type: ConstraintType = .equal) -> Self {
|
|
switch type {
|
|
case .equal:
|
|
pinTrailing(anchor, constant)
|
|
|
|
case .lessThanOrEqual:
|
|
pinTrailingLessThanOrEqualTo(anchor, constant)
|
|
|
|
case .greaterThanOrEqual:
|
|
pinLeadingGreaterThanOrEqualTo(anchor, constant)
|
|
}
|
|
return self
|
|
}
|
|
|
|
@discardableResult
|
|
public func pinTrailing(_ constant: CGFloat = 0.0) -> Self {
|
|
return pinTrailing(nil, constant)
|
|
}
|
|
|
|
@discardableResult
|
|
public func pinTrailing(_ anchor: NSLayoutXAxisAnchor? = nil, _ constant: CGFloat = 0.0) -> Self {
|
|
let found: NSLayoutXAxisAnchor? = anchor ?? superview?.trailingAnchor
|
|
if let found {
|
|
trailingAnchor.constraint(equalTo: found, constant: -constant, identifier: ConstraintIdentifier.trailing.description).isActive = true
|
|
}
|
|
return self
|
|
}
|
|
|
|
@discardableResult
|
|
public func pinTrailingLessThanOrEqualTo(_ anchor: NSLayoutXAxisAnchor? = nil, _ constant: CGFloat = 0.0) -> Self {
|
|
let found: NSLayoutXAxisAnchor? = anchor ?? superview?.trailingAnchor
|
|
if let found {
|
|
trailingAnchor.constraint(lessThanOrEqualTo: found, constant: -constant, identifier: ConstraintIdentifier.trailing.description).isActive = true
|
|
}
|
|
return self
|
|
}
|
|
|
|
@discardableResult
|
|
public func pinTrailingGreaterThanOrEqualTo(_ anchor: NSLayoutXAxisAnchor? = nil, _ constant: CGFloat = 0.0) -> Self {
|
|
let found: NSLayoutXAxisAnchor? = anchor ?? superview?.trailingAnchor
|
|
if let found {
|
|
trailingAnchor.constraint(greaterThanOrEqualTo: found, constant: -constant, identifier: ConstraintIdentifier.trailing.description).isActive = true
|
|
}
|
|
return self
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------
|
|
// MARK: - Debug Borders
|
|
//--------------------------------------------------
|
|
extension UIView {
|
|
|
|
internal func removeDebugBorder() {
|
|
layer.remove(layerName: "debug")
|
|
}
|
|
|
|
internal func addDebugBorder(color: UIColor = .red) {
|
|
//ensure you remove existing
|
|
removeDebugBorder()
|
|
|
|
//add bounds border
|
|
let borderLayer = CALayer()
|
|
borderLayer.name = "debugAreaLayer"
|
|
borderLayer.frame = bounds
|
|
borderLayer.bounds = bounds
|
|
borderLayer.borderWidth = VDSFormControls.widthBorder
|
|
borderLayer.borderColor = color.cgColor
|
|
layer.addSublayer(borderLayer)
|
|
|
|
//add touchborder if applicable
|
|
if type(of: self) is AppleGuidlinesTouchable.Type {
|
|
let faultToleranceX: CGFloat = max((45 - bounds.size.width) / 2.0, 0)
|
|
let faultToleranceY: CGFloat = max((45 - bounds.size.height) / 2.0, 0)
|
|
|
|
let touchableAreaPath = UIBezierPath(rect: bounds.insetBy(dx: -faultToleranceX, dy: -faultToleranceY))
|
|
let touchLayer = CAShapeLayer()
|
|
touchLayer.path = touchableAreaPath.cgPath
|
|
touchLayer.strokeColor = color.cgColor
|
|
touchLayer.fillColor = UIColor.clear.cgColor
|
|
touchLayer.lineWidth = VDSFormControls.widthBorder
|
|
touchLayer.opacity = 1.0
|
|
touchLayer.name = "debugTouchableAreaLayer"
|
|
touchLayer.zPosition = 100
|
|
touchLayer.frame = bounds
|
|
touchLayer.bounds = bounds
|
|
layer.addSublayer(touchLayer)
|
|
}
|
|
}
|
|
|
|
public var hasDebugBorder: Bool {
|
|
guard let layers = layer.sublayers else { return false }
|
|
return layers.compactMap{$0.name}.filter{$0.hasPrefix("debug")}.count > 0
|
|
}
|
|
|
|
public func debugBorder(show shouldShow: Bool = true, color: UIColor = .red) {
|
|
if shouldShow {
|
|
addDebugBorder(color: color)
|
|
} else {
|
|
removeDebugBorder()
|
|
}
|
|
if let view = self as? Handlerable {
|
|
view.updateView()
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------
|
|
// MARK: - CALayer
|
|
//--------------------------------------------------
|
|
extension CALayer {
|
|
func remove(layerName: String) {
|
|
guard let sublayers = sublayers else {
|
|
return
|
|
}
|
|
|
|
sublayers.forEach({ layer in
|
|
if layer.name?.hasPrefix(layerName) ?? false {
|
|
layer.removeFromSuperlayer()
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------
|
|
// MARK: - Borders
|
|
//--------------------------------------------------
|
|
extension UIView {
|
|
|
|
public func addBorder(side: UIRectEdge, width: CGFloat, color: UIColor, offset: CGFloat = 0) {
|
|
let layerName = borderLayerName(for: side)
|
|
layer.remove(layerName: layerName)
|
|
|
|
let borderLayer = CALayer()
|
|
borderLayer.backgroundColor = color.cgColor
|
|
borderLayer.name = layerName
|
|
|
|
switch side {
|
|
case .left:
|
|
borderLayer.frame = CGRect(x: 0, y: 0, width: width, height: frame.height)
|
|
case .right:
|
|
borderLayer.frame = CGRect(x: frame.width - width - offset, y: 0, width: width, height: frame.height)
|
|
case .top:
|
|
borderLayer.frame = CGRect(x: 0, y: 0, width: frame.width, height: width)
|
|
case .bottom:
|
|
borderLayer.frame = CGRect(x: 0, y: frame.height - width - offset, width: frame.width, height: width)
|
|
default:
|
|
break
|
|
}
|
|
|
|
layer.addSublayer(borderLayer)
|
|
}
|
|
|
|
public func removeBorders() {
|
|
layer.borderWidth = 0
|
|
layer.borderColor = nil
|
|
layer.remove(layerName: borderLayerName(for: .top))
|
|
layer.remove(layerName: borderLayerName(for: .left))
|
|
layer.remove(layerName: borderLayerName(for: .right))
|
|
layer.remove(layerName: borderLayerName(for: .bottom))
|
|
}
|
|
|
|
private func borderLayerName(for side: UIRectEdge) -> String {
|
|
switch side {
|
|
case .left:
|
|
return "leftBorderLayer"
|
|
case .right:
|
|
return "rightBorderLayer"
|
|
case .top:
|
|
return "topBorderLayer"
|
|
case .bottom:
|
|
return "bottomBorderLayer"
|
|
default:
|
|
return ""
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------
|
|
// MARK: - NSLayoutAnchor
|
|
//--------------------------------------------------
|
|
extension NSLayoutAnchor {
|
|
// These methods return an inactive constraint of the form thisAnchor = otherAnchor.
|
|
@discardableResult
|
|
@objc public func constraint(equalTo anchor: NSLayoutAnchor, identifier: String) -> NSLayoutConstraint {
|
|
let constraint = self.constraint(equalTo: anchor)
|
|
constraint.identifier = identifier
|
|
return constraint
|
|
}
|
|
|
|
@discardableResult
|
|
@objc public func constraint(greaterThanOrEqualTo anchor: NSLayoutAnchor, identifier: String) -> NSLayoutConstraint {
|
|
let constraint = self.constraint(greaterThanOrEqualTo: anchor)
|
|
constraint.identifier = identifier
|
|
return constraint
|
|
}
|
|
|
|
@discardableResult
|
|
@objc public func constraint(lessThanOrEqualTo anchor: NSLayoutAnchor, identifier: String) -> NSLayoutConstraint {
|
|
let constraint = self.constraint(lessThanOrEqualTo: anchor)
|
|
constraint.identifier = identifier
|
|
return constraint
|
|
}
|
|
|
|
|
|
@discardableResult
|
|
@objc public func constraint(equalTo anchor: NSLayoutAnchor, constant: CGFloat, identifier: String) -> NSLayoutConstraint {
|
|
let constraint = self.constraint(equalTo: anchor, constant: constant)
|
|
constraint.identifier = identifier
|
|
return constraint
|
|
}
|
|
|
|
@discardableResult
|
|
@objc public func constraint(greaterThanOrEqualTo anchor: NSLayoutAnchor, constant: CGFloat, identifier: String) -> NSLayoutConstraint {
|
|
let constraint = self.constraint(greaterThanOrEqualTo: anchor, constant: constant)
|
|
constraint.identifier = identifier
|
|
return constraint
|
|
}
|
|
|
|
@discardableResult
|
|
@objc public func constraint(lessThanOrEqualTo anchor: NSLayoutAnchor, constant: CGFloat, identifier: String) -> NSLayoutConstraint {
|
|
let constraint = self.constraint(lessThanOrEqualTo: anchor, constant: constant)
|
|
constraint.identifier = identifier
|
|
return constraint
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------
|
|
// MARK: - NSLayoutDimension
|
|
//--------------------------------------------------
|
|
extension NSLayoutDimension {
|
|
// These methods return an inactive constraint of the form thisVariable = constant.
|
|
@discardableResult
|
|
@objc public func constraint(equalToConstant c: CGFloat, identifier: String) -> NSLayoutConstraint {
|
|
let lc = constraint(equalToConstant: c)
|
|
lc.identifier = identifier
|
|
return lc
|
|
}
|
|
|
|
@discardableResult
|
|
@objc public func constraint(greaterThanOrEqualToConstant c: CGFloat, identifier: String) -> NSLayoutConstraint {
|
|
let lc = constraint(greaterThanOrEqualToConstant: c)
|
|
lc.identifier = identifier
|
|
return lc
|
|
}
|
|
|
|
@discardableResult
|
|
@objc public func constraint(lessThanOrEqualToConstant c: CGFloat, identifier: String) -> NSLayoutConstraint {
|
|
let lc = constraint(lessThanOrEqualToConstant: c)
|
|
lc.identifier = identifier
|
|
return lc
|
|
}
|
|
|
|
|
|
// These methods return an inactive constraint of the form thisAnchor = otherAnchor * multiplier.
|
|
@discardableResult
|
|
@objc public func constraint(equalTo anchor: NSLayoutDimension, multiplier m: CGFloat, identifier: String) -> NSLayoutConstraint {
|
|
let lc = constraint(equalTo: anchor, multiplier: m)
|
|
lc.identifier = identifier
|
|
return lc
|
|
}
|
|
|
|
@discardableResult
|
|
@objc public func constraint(greaterThanOrEqualTo anchor: NSLayoutDimension, multiplier m: CGFloat, identifier: String) -> NSLayoutConstraint {
|
|
let lc = constraint(greaterThanOrEqualTo: anchor ,multiplier: m)
|
|
lc.identifier = identifier
|
|
return lc
|
|
}
|
|
|
|
@discardableResult
|
|
@objc public func constraint(lessThanOrEqualTo anchor: NSLayoutDimension, multiplier m: CGFloat, identifier: String) -> NSLayoutConstraint {
|
|
let lc = constraint(lessThanOrEqualTo: anchor, multiplier: m)
|
|
lc.identifier = identifier
|
|
return lc
|
|
}
|
|
|
|
|
|
// These methods return an inactive constraint of the form thisAnchor = otherAnchor * multiplier + constant.
|
|
@discardableResult
|
|
@objc public func constraint(equalTo anchor: NSLayoutDimension, multiplier m: CGFloat, constant c: CGFloat, identifier: String) -> NSLayoutConstraint {
|
|
let lc = constraint(equalTo: anchor, multiplier: m, constant: c)
|
|
lc.identifier = identifier
|
|
return lc
|
|
}
|
|
|
|
@discardableResult
|
|
@objc public func constraint(greaterThanOrEqualTo anchor: NSLayoutDimension, multiplier m: CGFloat, constant c: CGFloat, identifier: String) -> NSLayoutConstraint {
|
|
let lc = constraint(greaterThanOrEqualTo: anchor, multiplier: m, constant: c)
|
|
lc.identifier = identifier
|
|
return lc
|
|
}
|
|
|
|
@discardableResult
|
|
@objc public func constraint(lessThanOrEqualTo anchor: NSLayoutDimension, multiplier m: CGFloat, constant c: CGFloat, identifier: String) -> NSLayoutConstraint {
|
|
let lc = constraint(lessThanOrEqualTo: anchor, multiplier: m, constant: c)
|
|
lc.identifier = identifier
|
|
return lc
|
|
}
|
|
|
|
}
|