added accessibilty actions
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
This commit is contained in:
parent
e3edf940c7
commit
50bb76d806
@ -126,14 +126,34 @@ open class LabelBase<ModelType: LabelModel>: UILabel, ModelHandlerable, Initable
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let attributes = viewModel.attributes, let text = model.text, let font = font, let textColor = textColor {
|
if let attributes = viewModel.attributes, let text = model.text, let font = font, let textColor = textColor {
|
||||||
|
//clear the arrays holding actions
|
||||||
|
accessibilityCustomActions = []
|
||||||
|
actions = []
|
||||||
|
|
||||||
|
//create the primary string
|
||||||
let startingAttributes = [NSAttributedString.Key.font: font, NSAttributedString.Key.foregroundColor: textColor]
|
let startingAttributes = [NSAttributedString.Key.font: font, NSAttributedString.Key.foregroundColor: textColor]
|
||||||
let mutableText = NSMutableAttributedString(string: text, attributes: startingAttributes)
|
let mutableText = NSMutableAttributedString(string: text, attributes: startingAttributes)
|
||||||
|
|
||||||
|
//loop through the models attributes
|
||||||
for attribute in attributes {
|
for attribute in attributes {
|
||||||
|
|
||||||
|
//add attribute on the string
|
||||||
attribute.setAttribute(on: mutableText)
|
attribute.setAttribute(on: mutableText)
|
||||||
|
|
||||||
|
//see if the attribute is Actionable
|
||||||
if let actionable = attribute as? LabelAttributeActionable{
|
if let actionable = attribute as? LabelAttributeActionable{
|
||||||
actions.append(actionable)
|
//create a accessibleAction
|
||||||
|
let customAccessibilityAction = customAccessibilityAction(range: actionable.range)
|
||||||
|
|
||||||
|
//create a wrapper for the attributes range, block and
|
||||||
|
actions.append(LabelAction(range: actionable.range, actionBlock: actionable.action, accessibilityID: customAccessibilityAction?.hashValue ?? -1))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//only enabled if enabled and has actions
|
||||||
|
isUserInteractionEnabled = !viewModel.disabled && !actions.isEmpty
|
||||||
|
|
||||||
|
//set the attributed text
|
||||||
attributedText = mutableText
|
attributedText = mutableText
|
||||||
} else {
|
} else {
|
||||||
text = viewModel.text
|
text = viewModel.text
|
||||||
@ -155,20 +175,41 @@ open class LabelBase<ModelType: LabelModel>: UILabel, ModelHandlerable, Initable
|
|||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Actionable
|
// MARK: - Actionable
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
private var tapGesture: UITapGestureRecognizer?
|
private var tapGesture: UITapGestureRecognizer? {
|
||||||
private var actions: [LabelAttributeActionable] = [] {
|
willSet {
|
||||||
|
if let tapGesture = tapGesture, newValue == nil {
|
||||||
|
removeGestureRecognizer(tapGesture)
|
||||||
|
} else if let gesture = newValue, tapGesture == nil {
|
||||||
|
addGestureRecognizer(gesture)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct LabelAction {
|
||||||
|
var range: NSRange
|
||||||
|
var actionBlock: Blocks.ActionBlock
|
||||||
|
var accessibilityId: Int = 0
|
||||||
|
|
||||||
|
func performAction() {
|
||||||
|
actionBlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
init(range: NSRange, actionBlock: @escaping Blocks.ActionBlock, accessibilityID: Int = 0) {
|
||||||
|
self.range = range
|
||||||
|
self.actionBlock = actionBlock
|
||||||
|
self.accessibilityId = accessibilityID
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var actions: [LabelAction] = [] {
|
||||||
didSet {
|
didSet {
|
||||||
isUserInteractionEnabled = !actions.isEmpty
|
|
||||||
if actions.isEmpty {
|
if actions.isEmpty {
|
||||||
if let tapGesture = tapGesture {
|
tapGesture = nil
|
||||||
removeGestureRecognizer(tapGesture)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
//add tap gesture
|
//add tap gesture
|
||||||
if tapGesture == nil {
|
if tapGesture == nil {
|
||||||
let singleTap = UITapGestureRecognizer(target: self, action: #selector(textLinkTapped))
|
let singleTap = UITapGestureRecognizer(target: self, action: #selector(textLinkTapped))
|
||||||
singleTap.numberOfTapsRequired = 1
|
singleTap.numberOfTapsRequired = 1
|
||||||
addGestureRecognizer(singleTap)
|
|
||||||
tapGesture = singleTap
|
tapGesture = singleTap
|
||||||
}
|
}
|
||||||
if actions.count > 1 {
|
if actions.count > 1 {
|
||||||
@ -184,9 +225,54 @@ open class LabelBase<ModelType: LabelModel>: UILabel, ModelHandlerable, Initable
|
|||||||
for actionable in actions {
|
for actionable in actions {
|
||||||
// This determines if we tapped on the desired range of text.
|
// This determines if we tapped on the desired range of text.
|
||||||
if gesture.didTapAttributedTextInLabel(self, inRange: actionable.range) {
|
if gesture.didTapAttributedTextInLabel(self, inRange: actionable.range) {
|
||||||
actionable.action()
|
actionable.performAction()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Accessibility For Actions
|
||||||
|
//--------------------------------------------------
|
||||||
|
private func customAccessibilityAction(range: NSRange) -> UIAccessibilityCustomAction? {
|
||||||
|
|
||||||
|
guard let text = text else { return nil }
|
||||||
|
//TODO: accessibilityHint for Label
|
||||||
|
// if accessibilityHint == nil {
|
||||||
|
// accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: "swipe_to_select_with_action_hint")
|
||||||
|
// }
|
||||||
|
|
||||||
|
let actionText = NSString(string: text).substring(with: range)
|
||||||
|
let accessibleAction = UIAccessibilityCustomAction(name: actionText, target: self, selector: #selector(accessibilityCustomAction(_:)))
|
||||||
|
accessibilityCustomActions?.append(accessibleAction)
|
||||||
|
|
||||||
|
return accessibleAction
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc public func accessibilityCustomAction(_ action: UIAccessibilityCustomAction) {
|
||||||
|
|
||||||
|
for actionable in actions {
|
||||||
|
if action.hash == actionable.accessibilityId {
|
||||||
|
actionable.performAction()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open override func accessibilityActivate() -> Bool {
|
||||||
|
|
||||||
|
guard let accessibleActions = accessibilityCustomActions else { return false }
|
||||||
|
|
||||||
|
for actionable in actions {
|
||||||
|
for action in accessibleActions {
|
||||||
|
if action.hash == actionable.accessibilityId {
|
||||||
|
actionable.performAction()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user