refactored out extensions into files
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
This commit is contained in:
parent
ce340fa34e
commit
342357820f
@ -106,6 +106,9 @@
|
||||
EAC925842911C63100091998 /* Colorable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA5EEDF28F49DB3003B3210 /* Colorable.swift */; };
|
||||
EAC9258C2911C9DE00091998 /* InputField.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAC925872911C9DE00091998 /* InputField.swift */; };
|
||||
EAC9258F2911C9DE00091998 /* EntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAC9258B2911C9DE00091998 /* EntryField.swift */; };
|
||||
EAD062A72A3B67770015965D /* UIView+CALayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAD062A62A3B67770015965D /* UIView+CALayer.swift */; };
|
||||
EAD062A92A3B67B10015965D /* NSLayoutAnchor.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAD062A82A3B67B10015965D /* NSLayoutAnchor.swift */; };
|
||||
EAD062AB2A3B67D00015965D /* NSLayoutDimension.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAD062AA2A3B67D00015965D /* NSLayoutDimension.swift */; };
|
||||
EAD8D2C128BFDE8B006EB6A6 /* UIGestureRecognizer+Publisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAD8D2C028BFDE8B006EB6A6 /* UIGestureRecognizer+Publisher.swift */; };
|
||||
EAF1FE9929D4850E00101452 /* Clickable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF1FE9829D4850E00101452 /* Clickable.swift */; };
|
||||
EAF1FE9B29DB1A6000101452 /* Changeable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF1FE9A29DB1A6000101452 /* Changeable.swift */; };
|
||||
@ -237,6 +240,9 @@
|
||||
EAC925822911B35300091998 /* TextLinkCaret.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextLinkCaret.swift; sourceTree = "<group>"; };
|
||||
EAC925872911C9DE00091998 /* InputField.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InputField.swift; sourceTree = "<group>"; };
|
||||
EAC9258B2911C9DE00091998 /* EntryField.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EntryField.swift; sourceTree = "<group>"; };
|
||||
EAD062A62A3B67770015965D /* UIView+CALayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+CALayer.swift"; sourceTree = "<group>"; };
|
||||
EAD062A82A3B67B10015965D /* NSLayoutAnchor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSLayoutAnchor.swift; sourceTree = "<group>"; };
|
||||
EAD062AA2A3B67D00015965D /* NSLayoutDimension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSLayoutDimension.swift; sourceTree = "<group>"; };
|
||||
EAD8D2C028BFDE8B006EB6A6 /* UIGestureRecognizer+Publisher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIGestureRecognizer+Publisher.swift"; sourceTree = "<group>"; };
|
||||
EAF1FE9829D4850E00101452 /* Clickable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Clickable.swift; sourceTree = "<group>"; };
|
||||
EAF1FE9A29DB1A6000101452 /* Changeable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Changeable.swift; sourceTree = "<group>"; };
|
||||
@ -429,12 +435,15 @@
|
||||
EAF7F0992899B17200B287F5 /* CATransaction.swift */,
|
||||
EA33622D2891EA3C0071C351 /* DispatchQueue+Once.swift */,
|
||||
EABFEB632A26473700C4C106 /* NSAttributedString.swift */,
|
||||
EAD062A82A3B67B10015965D /* NSLayoutAnchor.swift */,
|
||||
EAD062AA2A3B67D00015965D /* NSLayoutDimension.swift */,
|
||||
EAB2376529E9952D00AABE9A /* UIApplication.swift */,
|
||||
EA3361A7288B23300071C351 /* UIColor.swift */,
|
||||
EA81410F2A127066004F60D2 /* UIColor+VDSColor.swift */,
|
||||
EA33623D2892EE950071C351 /* UIDevice.swift */,
|
||||
EAF7F0B6289C12A600B287F5 /* UITapGestureRecognizer.swift */,
|
||||
EAB5FED329267EB300998C17 /* UIView.swift */,
|
||||
EAD062A62A3B67770015965D /* UIView+CALayer.swift */,
|
||||
EAB5FF0029424ACB00998C17 /* UIControl.swift */,
|
||||
EA985C662970C21600F2FF2E /* VDSLayout.swift */,
|
||||
);
|
||||
@ -884,6 +893,7 @@
|
||||
EA33624728931B050071C351 /* Initable.swift in Sources */,
|
||||
EAF7F0A4289B017C00B287F5 /* LabelAttributeModel.swift in Sources */,
|
||||
EA5F86D02A1F936100BC83E4 /* TabsContainer.swift in Sources */,
|
||||
EAD062A92A3B67B10015965D /* NSLayoutAnchor.swift in Sources */,
|
||||
EAF7F0B1289B177F00B287F5 /* ColorLabelAttribute.swift in Sources */,
|
||||
EAC9258F2911C9DE00091998 /* EntryField.swift in Sources */,
|
||||
EAB1D2EA28AE84AA00DAE764 /* UIControlPublisher.swift in Sources */,
|
||||
@ -927,6 +937,7 @@
|
||||
EAB2376629E9952D00AABE9A /* UIApplication.swift in Sources */,
|
||||
EAB5FED429267EB300998C17 /* UIView.swift in Sources */,
|
||||
EAB2376829E9992800AABE9A /* TooltipAlertViewController.swift in Sources */,
|
||||
EAD062AB2A3B67D00015965D /* NSLayoutDimension.swift in Sources */,
|
||||
EA33623E2892EE950071C351 /* UIDevice.swift in Sources */,
|
||||
EA985C692971B90B00F2FF2E /* IconSize.swift in Sources */,
|
||||
EA985C672970C21600F2FF2E /* VDSLayout.swift in Sources */,
|
||||
@ -941,6 +952,7 @@
|
||||
EA1F266628B945070033E859 /* RadioSwatchGroup.swift in Sources */,
|
||||
EA596ABF2A16B4F500300C4B /* Tabs.swift in Sources */,
|
||||
EAC71A212A2E1DC000E47A9F /* SelectorItemBase.swift in Sources */,
|
||||
EAD062A72A3B67770015965D /* UIView+CALayer.swift in Sources */,
|
||||
EA985BEC2968A91200F2FF2E /* TitleLockupTitleModel.swift in Sources */,
|
||||
5FC35BE328D51405004EBEAC /* Button.swift in Sources */,
|
||||
);
|
||||
|
||||
58
VDS/Extensions/NSLayoutAnchor.swift
Normal file
58
VDS/Extensions/NSLayoutAnchor.swift
Normal file
@ -0,0 +1,58 @@
|
||||
//
|
||||
// NSLayoutAnchor.swift
|
||||
// VDS
|
||||
//
|
||||
// Created by Matt Bruce on 6/15/23.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
|
||||
//--------------------------------------------------
|
||||
// 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
|
||||
}
|
||||
}
|
||||
84
VDS/Extensions/NSLayoutDimension.swift
Normal file
84
VDS/Extensions/NSLayoutDimension.swift
Normal file
@ -0,0 +1,84 @@
|
||||
//
|
||||
// NSLayoutDimension.swift
|
||||
// VDS
|
||||
//
|
||||
// Created by Matt Bruce on 6/15/23.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
|
||||
//--------------------------------------------------
|
||||
// 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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
140
VDS/Extensions/UIView+CALayer.swift
Normal file
140
VDS/Extensions/UIView+CALayer.swift
Normal file
@ -0,0 +1,140 @@
|
||||
//
|
||||
// UIView+CALayer.swift
|
||||
// VDS
|
||||
//
|
||||
// Created by Matt Bruce on 6/15/23.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
import VDSFormControlsTokens
|
||||
|
||||
//--------------------------------------------------
|
||||
// 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 ""
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -396,256 +396,3 @@ extension UIView {
|
||||
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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user