fixed textlinkcaret issue
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
This commit is contained in:
parent
fb4a473f42
commit
c2d200e7f2
@ -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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user