vds_ios/VDS/Extensions/UIView.swift
Matt Bruce e91465f423 added removal extension
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2023-05-16 15:31:42 -05:00

186 lines
6.0 KiB
Swift

//
// UIView.swift
// VDS
//
// Created by Matt Bruce on 11/17/22.
//
import Foundation
import UIKit
import VDSFormControlsTokens
extension UIView {
public func pin(_ view: UIView, with edges: UIEdgeInsets = UIEdgeInsets.zero) {
leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: edges.left).isActive = true
trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -edges.right).isActive = true
topAnchor.constraint(equalTo: view.topAnchor, constant: edges.top).isActive = true
bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -edges.bottom).isActive = true
}
public func pinToSuperView(_ edges: UIEdgeInsets = UIEdgeInsets.zero) {
if let superview {
pin(superview, with: edges)
}
}
@discardableResult
public func height(_ constant: CGFloat) -> Self {
heightAnchor.constraint(equalToConstant: constant).isActive = true
return self
}
@discardableResult
public func heightGreaterThanEqual(_ constant: CGFloat) -> Self {
heightAnchor.constraint(greaterThanOrEqualToConstant: constant).isActive = true
return self
}
@discardableResult
public func heightLessThanEqual(_ constant: CGFloat) -> Self {
heightAnchor.constraint(lessThanOrEqualToConstant: constant).isActive = true
return self
}
@discardableResult
public func width(_ constant: CGFloat) -> Self {
widthAnchor.constraint(equalToConstant: constant).isActive = true
return self
}
@discardableResult
public func widthGreaterThanEqual(_ constant: CGFloat) -> Self {
widthAnchor.constraint(greaterThanOrEqualToConstant: constant).isActive = true
return self
}
@discardableResult
public func widthLessThanEqual(_ constant: CGFloat) -> Self {
widthAnchor.constraint(lessThanOrEqualToConstant: constant).isActive = true
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).isActive = true
}
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).isActive = true
}
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).isActive = true
}
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).isActive = true
}
return self
}
}
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()
}
}
}
extension CALayer {
func remove(layerName: String) {
sublayers?.forEach({ layer in
if layer.name?.hasPrefix(layerName) ?? false {
layer.removeFromSuperlayer()
}
})
}
}