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 {
|
||||
//clear the arrays holding actions
|
||||
accessibilityCustomActions = []
|
||||
actions = []
|
||||
|
||||
//create the primary string
|
||||
let startingAttributes = [NSAttributedString.Key.font: font, NSAttributedString.Key.foregroundColor: textColor]
|
||||
let mutableText = NSMutableAttributedString(string: text, attributes: startingAttributes)
|
||||
|
||||
//loop through the models attributes
|
||||
for attribute in attributes {
|
||||
|
||||
//add attribute on the string
|
||||
attribute.setAttribute(on: mutableText)
|
||||
|
||||
//see if the attribute is Actionable
|
||||
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
|
||||
} else {
|
||||
text = viewModel.text
|
||||
@ -155,20 +175,41 @@ open class LabelBase<ModelType: LabelModel>: UILabel, ModelHandlerable, Initable
|
||||
//--------------------------------------------------
|
||||
// MARK: - Actionable
|
||||
//--------------------------------------------------
|
||||
private var tapGesture: UITapGestureRecognizer?
|
||||
private var actions: [LabelAttributeActionable] = [] {
|
||||
private var tapGesture: UITapGestureRecognizer? {
|
||||
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 {
|
||||
isUserInteractionEnabled = !actions.isEmpty
|
||||
if actions.isEmpty {
|
||||
if let tapGesture = tapGesture {
|
||||
removeGestureRecognizer(tapGesture)
|
||||
}
|
||||
tapGesture = nil
|
||||
} else {
|
||||
//add tap gesture
|
||||
if tapGesture == nil {
|
||||
let singleTap = UITapGestureRecognizer(target: self, action: #selector(textLinkTapped))
|
||||
singleTap.numberOfTapsRequired = 1
|
||||
addGestureRecognizer(singleTap)
|
||||
tapGesture = singleTap
|
||||
}
|
||||
if actions.count > 1 {
|
||||
@ -184,9 +225,54 @@ open class LabelBase<ModelType: LabelModel>: UILabel, ModelHandlerable, Initable
|
||||
for actionable in actions {
|
||||
// This determines if we tapped on the desired range of text.
|
||||
if gesture.didTapAttributedTextInLabel(self, inRange: actionable.range) {
|
||||
actionable.action()
|
||||
actionable.performAction()
|
||||
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