fixed textlinkcaret issue

Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
This commit is contained in:
Matt Bruce 2023-05-08 16:08:04 -05:00
parent fb4a473f42
commit c2d200e7f2

View File

@ -28,11 +28,7 @@ open class TextLinkCaret: ButtonBase {
TextStyle.boldBodyLarge TextStyle.boldBodyLarge
} }
private var caretView = CaretView().with { private var imageAttribute: ImageSpaceLabelAttribute?
$0.size = CaretView.Size.small(.vertical)
$0.lineWidth = 2
}
private var imageAttribute: ImageLabelAttribute?
open override var attributes: [any LabelAttributeModel]? { open override var attributes: [any LabelAttributeModel]? {
guard let imageAttribute else { return nil } guard let imageAttribute else { return nil }
@ -49,19 +45,7 @@ open class TextLinkCaret: ButtonBase {
private var height: CGFloat { private var height: CGFloat {
44 44
} }
private var _text: String?
open override var text: String? {
get{ _text }
set {
var updatedText = newValue ?? ""
updatedText = iconPosition == .right ? "\(updatedText) " : " \(updatedText)"
_text = updatedText
setNeedsUpdate()
}
}
open override var textColor: UIColor { open override var textColor: UIColor {
textColorConfiguration.getColor(self) textColorConfiguration.getColor(self)
} }
@ -92,9 +76,6 @@ open class TextLinkCaret: ButtonBase {
//-------------------------------------------------- //--------------------------------------------------
open override func setup() { open override func setup() {
super.setup() super.setup()
let size = caretView.size!.dimensions()
caretView.frame = .init(x: 0, y: 0, width: size.width, height: size.height)
} }
open override func reset() { open override func reset() {
@ -112,204 +93,56 @@ open class TextLinkCaret: ButtonBase {
var itemWidth = size.width var itemWidth = size.width
if let caretWidth = caretView.size?.dimensions().width { if let caretWidth = imageAttribute?.width {
itemWidth += caretWidth itemWidth += caretWidth
} }
return CGSize(width: itemWidth, height: size.height) return CGSize(width: itemWidth, height: size.height)
} }
open override func updateView() { open override func updateView() {
let updatedText = text ?? "" let updatedText = text ?? ""
caretView.surface = surface
caretView.disabled = disabled imageAttribute = ImageSpaceLabelAttribute(tintColor: textColor, position: iconPosition)
caretView.direction = iconPosition == .right ? CaretView.Direction.right : CaretView.Direction.left
let image = caretView.getImage()
let location = iconPosition == .right ? updatedText.count : 0
imageAttribute = ImageLabelAttribute(location: location,
image: image,
tintColor: textColor)
super.updateView() super.updateView()
} }
} }
extension UIView { extension TextLinkCaret {
public func getImage() -> UIImage { struct ImageSpaceLabelAttribute: LabelAttributeModel {
let renderer = UIGraphicsImageRenderer(size: self.bounds.size) var id: UUID = .init()
let image = renderer.image { ctx in var location: Int = 0
self.drawHierarchy(in: self.bounds, afterScreenUpdates: true) var length: Int = 1
} var tintColor: UIColor
return image var position: IconPosition
} var spacerWidth: CGFloat = 2.0
} var width: CGFloat { caretSize.width + spacerWidth }
var caretSize: CGSize { Icon.Size.xsmall.dimensions }
internal class CaretView: View { init(tintColor: UIColor, position: IconPosition) {
//------------------------------------------------------ self.tintColor = tintColor
// MARK: - Properties self.position = position
//------------------------------------------------------
private var caretPath: UIBezierPath = UIBezierPath()
public var lineWidth: CGFloat = 1 { didSet{ setNeedsUpdate() } }
public var direction: Direction = .right { didSet{ setNeedsUpdate() } }
public var size: Size? { didSet{ setNeedsUpdate() } }
public var colorConfiguration: AnyColorable = ViewColorConfiguration().with {
$0.setSurfaceColors(VDSColor.elementsSecondaryOnlight, VDSColor.elementsSecondaryOndark, forDisabled: true)
$0.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark, forDisabled: false)
}.eraseToAnyColorable()
//------------------------------------------------------
// MARK: - Constraints
//------------------------------------------------------
/// Sizes of CaretView are derived from InVision design specs. They are provided for convenience.
public enum Size {
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 setAttribute(on attributedString: NSMutableAttributedString) {
func dimensions() -> CGSize { let imageAttr = ImageLabelAttribute(location: location, imageName: "\(position.rawValue)-caret-bold", frame: .init(x: 0, y: 0, width: caretSize.width, height: caretSize.height), tintColor: tintColor)
let spaceAttr = ImageLabelAttribute(location: 0, imageName: "info", frame: .init(x: 0, y: 0, width: spacerWidth, height: 5.0), tintColor: .clear)
switch self { guard let image = try? imageAttr.getAttachment(),
case .small(let o): let spacer = try? spaceAttr.getAttachment() else { return }
return o == .vertical ? CGSize(width: 6.9, height: 10.96) : CGSize(width: 10.96, height: 6.9)
if position == .right {
case .medium(let o): attributedString.append(NSAttributedString(attachment: spacer))
return o == .vertical ? CGSize(width: 9.9, height: 16.96) : CGSize(width: 16.96, height: 9.9) attributedString.append(NSAttributedString(attachment: image))
} else {
case .large(let o): attributedString.insert(NSAttributedString(attachment: image), at: 0)
return o == .vertical ? CGSize(width: 14.9, height: 24.96) : CGSize(width: 24.96, height: 14.9) attributedString.insert(NSAttributedString(attachment: spacer), at: 1)
} }
} }
}
//------------------------------------------------------
// 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)
}
public convenience init(size: Size){
let dimensions = size.dimensions()
self.init(frame: .init(x: 0, y: 0, width: dimensions.width, height: dimensions.height))
self.size = size
}
//------------------------------------------------------
// MARK: - Setup
//------------------------------------------------------
override open func setup() {
super.setup()
defaultState()
isAccessibilityElement = true func isEqual(_ equatable: ImageSpaceLabelAttribute) -> Bool {
accessibilityTraits = .link return id == equatable.id && range == equatable.range
}
//------------------------------------------------------
// 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
} }
} }