updated lextLinkCaret
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
This commit is contained in:
parent
74c1a47257
commit
10dc7e880a
@ -11,7 +11,7 @@ import VDSColorTokens
|
||||
import VDSFormControlsTokens
|
||||
import Combine
|
||||
|
||||
public enum TextLinkIconPosition: String, CaseIterable {
|
||||
public enum TextLinkCaretPosition: String, CaseIterable {
|
||||
case left, right
|
||||
}
|
||||
|
||||
@ -22,14 +22,26 @@ open class TextLinkCaret: Control {
|
||||
// MARK: - Private Properties
|
||||
//--------------------------------------------------
|
||||
private var heightConstraint: NSLayoutConstraint?
|
||||
private var label = Label()
|
||||
|
||||
private let containerView = UIView().with{
|
||||
$0.translatesAutoresizingMaskIntoConstraints = false
|
||||
}
|
||||
|
||||
private var label = Label().with {
|
||||
$0.typograpicalStyle = TypographicalStyle.BoldBodyLarge
|
||||
}
|
||||
|
||||
private var caretView = CaretView().with {
|
||||
$0.size = CaretView.CaretSize.small(.vertical)
|
||||
$0.lineWidth = 2
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
open var text: String? { didSet { didChange() } }
|
||||
|
||||
open var iconPosition: TextLinkIconPosition = .right { didSet { didChange() } }
|
||||
open var iconPosition: TextLinkCaretPosition = .right { didSet { didChange() } }
|
||||
|
||||
private var height: CGFloat {
|
||||
44
|
||||
@ -62,21 +74,55 @@ open class TextLinkCaret: Control {
|
||||
|
||||
open override func setup() {
|
||||
super.setup()
|
||||
|
||||
addSubview(label)
|
||||
|
||||
//add tapGesture to self
|
||||
publisher(for: UITapGestureRecognizer()).sink { [weak self] _ in
|
||||
self?.sendActions(for: .touchUpInside)
|
||||
}.store(in: &subscribers)
|
||||
|
||||
//pin stackview to edges
|
||||
label.topAnchor.constraint(equalTo: topAnchor).isActive = true
|
||||
label.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
|
||||
label.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
|
||||
label.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
|
||||
|
||||
|
||||
addSubview(containerView)
|
||||
containerView.addSubview(label)
|
||||
containerView.addSubview(caretView)
|
||||
|
||||
//constraints
|
||||
heightAnchor.constraint(equalToConstant: height).isActive = true
|
||||
|
||||
containerView.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
|
||||
containerView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
|
||||
containerView.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
|
||||
containerView.heightAnchor.constraint(lessThanOrEqualToConstant: height).isActive = true
|
||||
|
||||
label.topAnchor.constraint(equalTo: containerView.topAnchor).isActive = true
|
||||
label.bottomAnchor.constraint(equalTo: containerView.bottomAnchor).isActive = true
|
||||
label.widthAnchor.constraint(lessThanOrEqualTo: containerView.widthAnchor, multiplier: 0.90).isActive = true
|
||||
caretView.bottomAnchor.constraint(lessThanOrEqualTo: label.bottomAnchor, constant: -3).isActive = true
|
||||
caretView.setConstraints()
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Constraints
|
||||
//--------------------------------------------------
|
||||
private var caretLeadingConstraint: NSLayoutConstraint?
|
||||
private var caretTrailingConstraint: NSLayoutConstraint?
|
||||
private var labelConstraint: NSLayoutConstraint?
|
||||
|
||||
private func setConstraints(){
|
||||
caretLeadingConstraint?.isActive = false
|
||||
caretTrailingConstraint?.isActive = false
|
||||
labelConstraint?.isActive = false
|
||||
if iconPosition == .right {
|
||||
labelConstraint = label.leadingAnchor.constraint(equalTo: containerView.leadingAnchor)
|
||||
caretLeadingConstraint = caretView.leadingAnchor.constraint(equalTo: label.trailingAnchor, constant: 4)
|
||||
caretTrailingConstraint = caretView.trailingAnchor.constraint(lessThanOrEqualTo: containerView.trailingAnchor)
|
||||
} else {
|
||||
labelConstraint = label.trailingAnchor.constraint(lessThanOrEqualTo: containerView.trailingAnchor)
|
||||
caretLeadingConstraint = caretView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor)
|
||||
caretTrailingConstraint = caretView.trailingAnchor.constraint(equalTo: label.leadingAnchor, constant: -4)
|
||||
}
|
||||
caretTrailingConstraint?.isActive = true
|
||||
caretLeadingConstraint?.isActive = true
|
||||
labelConstraint?.isActive = true
|
||||
self.layoutIfNeeded()
|
||||
}
|
||||
|
||||
open override func reset() {
|
||||
@ -91,8 +137,170 @@ open class TextLinkCaret: Control {
|
||||
open override func updateView() {
|
||||
label.surface = surface
|
||||
label.disabled = disabled
|
||||
label.typograpicalStyle = TypographicalStyle.BoldBodyLarge
|
||||
label.text = text ?? ""
|
||||
label.text = text
|
||||
|
||||
caretView.direction = iconPosition == .right ? CaretView.Direction.right : CaretView.Direction.left
|
||||
setConstraints()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal class CaretView: View {
|
||||
//------------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//------------------------------------------------------
|
||||
private var caretPath: UIBezierPath = UIBezierPath()
|
||||
|
||||
public var lineWidth: CGFloat = 1 { didSet{ didChange() } }
|
||||
|
||||
public var direction: Direction = .right { didSet{ didChange() } }
|
||||
|
||||
public var size: CaretSize? { didSet{ didChange() } }
|
||||
|
||||
public var colorConfiguration: AnyColorable = DisabledSurfaceColorConfiguration().with {
|
||||
$0.disabled.lightColor = VDSColor.elementsSecondaryOnlight
|
||||
$0.disabled.darkColor = VDSColor.elementsSecondaryOndark
|
||||
$0.enabled.lightColor = VDSColor.elementsPrimaryOnlight
|
||||
$0.enabled.darkColor = VDSColor.elementsPrimaryOndark
|
||||
}.eraseToAnyColorable()
|
||||
|
||||
|
||||
//------------------------------------------------------
|
||||
// MARK: - Constraints
|
||||
//------------------------------------------------------
|
||||
|
||||
/// Sizes of CaretView are derived from InVision design specs. They are provided for convenience.
|
||||
public enum CaretSize {
|
||||
case small(Orientation)
|
||||
case medium(Orientation)
|
||||
case large(Orientation)
|
||||
|
||||
/// Orientation based on the longest line of the view.
|
||||
public enum Orientation {
|
||||
case vertical
|
||||
case horizontal
|
||||
}
|
||||
|
||||
/// Dimensions of container; provided by InVision design.
|
||||
func dimensions() -> CGSize {
|
||||
|
||||
switch self {
|
||||
case .small(let o):
|
||||
return o == .vertical ? CGSize(width: 6.9, height: 10.96) : CGSize(width: 10.96, height: 6.9)
|
||||
|
||||
case .medium(let o):
|
||||
return o == .vertical ? CGSize(width: 9.9, height: 16.96) : CGSize(width: 16.96, height: 9.9)
|
||||
|
||||
case .large(let o):
|
||||
return o == .vertical ? CGSize(width: 14.9, height: 24.96) : CGSize(width: 24.96, height: 14.9)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------
|
||||
// MARK: - Initialization
|
||||
//------------------------------------------------------
|
||||
|
||||
public override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
}
|
||||
|
||||
public convenience init(lineWidth: CGFloat) {
|
||||
self.init(frame: .zero)
|
||||
self.lineWidth = lineWidth
|
||||
}
|
||||
|
||||
required public init?(coder aDecoder: NSCoder) {
|
||||
super.init(coder: aDecoder)
|
||||
fatalError("CaretView xib not supported.")
|
||||
}
|
||||
|
||||
required public convenience init() {
|
||||
self.init(frame: .zero)
|
||||
}
|
||||
|
||||
//------------------------------------------------------
|
||||
// MARK: - Setup
|
||||
//------------------------------------------------------
|
||||
|
||||
override open func setup() {
|
||||
super.setup()
|
||||
defaultState()
|
||||
}
|
||||
|
||||
//------------------------------------------------------
|
||||
// MARK: - Drawing
|
||||
//------------------------------------------------------
|
||||
|
||||
/// The direction the caret will be pointing to.
|
||||
public enum Direction: Int {
|
||||
case left
|
||||
case right
|
||||
case down
|
||||
case up
|
||||
}
|
||||
|
||||
override func draw(_ rect: CGRect) {
|
||||
super.draw(rect)
|
||||
|
||||
caretPath.removeAllPoints()
|
||||
caretPath.lineJoinStyle = .miter
|
||||
caretPath.lineWidth = lineWidth
|
||||
|
||||
let inset = lineWidth / 2
|
||||
let halfWidth = frame.size.width / 2
|
||||
let halfHeight = frame.size.height / 2
|
||||
|
||||
switch direction {
|
||||
case .up:
|
||||
caretPath.move(to: CGPoint(x: inset, y: frame.size.height - inset))
|
||||
caretPath.addLine(to: CGPoint(x: halfWidth, y: inset))
|
||||
caretPath.addLine(to: CGPoint(x: frame.size.width, y: frame.size.height))
|
||||
|
||||
case .right:
|
||||
caretPath.move(to: CGPoint(x: inset, y: inset))
|
||||
caretPath.addLine(to: CGPoint(x: frame.size.width - inset, y: halfHeight))
|
||||
caretPath.addLine(to: CGPoint(x: inset, y: frame.size.height - inset))
|
||||
|
||||
case .down:
|
||||
caretPath.move(to: CGPoint(x: inset, y: inset))
|
||||
caretPath.addLine(to: CGPoint(x: halfWidth, y: frame.size.height - inset))
|
||||
caretPath.addLine(to: CGPoint(x: frame.size.width - inset, y: inset))
|
||||
|
||||
case .left:
|
||||
caretPath.move(to: CGPoint(x: frame.size.width - inset, y: inset))
|
||||
caretPath.addLine(to: CGPoint(x: inset, y: halfHeight))
|
||||
caretPath.addLine(to: CGPoint(x: frame.size.width - inset, y: frame.size.height - inset))
|
||||
}
|
||||
|
||||
let color = colorConfiguration.getColor(self)
|
||||
color.setStroke()
|
||||
caretPath.stroke()
|
||||
}
|
||||
|
||||
override func updateView() {
|
||||
setNeedsDisplay()
|
||||
}
|
||||
|
||||
//------------------------------------------------------
|
||||
// MARK: - Methods
|
||||
//------------------------------------------------------
|
||||
public func setLineColor(_ color: UIColor) {
|
||||
setNeedsDisplay()
|
||||
}
|
||||
|
||||
public func defaultState() {
|
||||
isOpaque = false
|
||||
isHidden = false
|
||||
backgroundColor = .clear
|
||||
}
|
||||
|
||||
/// Ensure you have defined a CaretSize with Orientation before calling.
|
||||
public func setConstraints() {
|
||||
|
||||
guard let dimensions = size?.dimensions() else { return }
|
||||
|
||||
heightAnchor.constraint(equalToConstant: dimensions.height).isActive = true
|
||||
widthAnchor.constraint(equalToConstant: dimensions.width).isActive = true
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user