-
Notifications
You must be signed in to change notification settings - Fork 45
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
AttributedLabel Accessibility Links #537
base: main
Are you sure you want to change the base?
Conversation
@@ -389,7 +364,7 @@ extension AttributedLabel { | |||
} | |||
|
|||
assert( | |||
alignments.count == 1, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was causing a crash in the demo app.
Someone went through the trouble of writing the nil case below, it'd be a shame never to use it.
e5ccc90
to
91e208b
Compare
91e208b
to
173630b
Compare
private var accessibilityLinkIndex = -1 | ||
|
||
/// These elements need to be retained by the view, and cannot be created inside the | ||
/// `accessibilityCustomRotors` getter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This concern about the elements being retained is still valid. We cannot pass back unretained elements created within the itemSearchBlock
.
The trick here is the elements are now retained in an array which is itself captured by the itemSearchBlock
.
Once VoiceOver releases the rotor these elements all get deallocated and then will be recreated the next time VoiceOver requests the rotor.
ece74e1
to
8ff1979
Compare
8ff1979
to
881411f
Compare
extension BidirectionalCollection where Element: Equatable, Element: NSObjectProtocol { | ||
private func itemSearch(_ predicate: UIAccessibilityCustomRotorSearchPredicate) -> UIAccessibilityCustomRotorItemResult? { | ||
guard let first else { return nil } | ||
guard let currentItem = predicate.currentItem.targetElement as? Element, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thinking outloud, im surprised to see both the generic constraint and this dynamic check; are both required?
This PR migrates
AttributedLabel
's link rotor from a stateful to functional pattern, eliminating the need for two variables and preventing voiceover from getting out of sync.I also fixed a bug in
links(at location: CGPoint)
that could cause a crash if theAttributedString
lacked a specifiedNSTextAlignment
.