-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Added attributed versions of accessibilityLabel, accessibilityHint, accessibilityValue #554
Conversation
…d accessibilityValue
🚫 CI failed with log |
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.
Thanks for working on this! Overall, LGTM. But let's sort out a few questions before merging.
Source/ASDisplayNode.h
Outdated
@@ -716,8 +716,11 @@ extern NSInteger const ASDefaultDrawingPriority; | |||
// Accessibility support | |||
@property (nonatomic, assign) BOOL isAccessibilityElement; | |||
@property (nonatomic, copy, nullable) NSString *accessibilityLabel; | |||
@property (nullable, nonatomic, copy) NSAttributedString *accessibilityAttributedLabel API_AVAILABLE(ios(11.0),tvos(11.0)); |
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.
To follow the existing convention, let's put nullable
last. So (nonatomic, copy, nullable)
NSArray *attributedLabels = [labeledNodes valueForKey:@"accessibilityAttributedLabel"]; | ||
NSMutableAttributedString *attributedLabel = [NSMutableAttributedString new]; | ||
[attributedLabels enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { | ||
if (idx != 0) |
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.
The convention is to use curly brackets regardless of the number of statements followed.
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.
Sorry I thought I followed convention because I saw this in _PendingState.mm a lot for single statements (L375, L377), but I'll change my code to use curly braces.
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.
Yeah, we need to have it written down in CONTRIBUTING.md
. Others may disagree, but I personally follow this convention (as much as possible).
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.
I wouldn't change it for applyToView:withSpecialPropertiesHandling:
though since every flag check seems to skip the curly braces
Source/Private/_ASPendingState.mm
Outdated
@@ -586,9 +595,26 @@ - (NSString *)accessibilityLabel | |||
|
|||
- (void)setAccessibilityLabel:(NSString *)newAccessibilityLabel | |||
{ | |||
_flags.setAccessibilityLabel = YES; | |||
if (accessibilityLabel != newAccessibilityLabel) { |
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.
Hm, are we comparing strings here?
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.
Yes, but this is from the original implementation: https://github.com/fruitcoder/Texture/blob/master/Source/Private/_ASPendingState.mm#L590
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.
Yes, I see you follow this implementation throughout your changes. I should have asked better questions, sorry.
Is there any reason to compare memory addresses here? Is the original implementation correct/acceptable?
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.
TBO I would compare those Strings with isEqualToString:
, since if they are equal (by means of isEqualToString), we don't have to do anything.
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.
I agree. I'd do it the right way and not worry about the perf implication of isEqualToString
, compared to ==
, especially because those labels aren't changed often I believe. Would you mind taking this opportunity to do an audit in this file and switch to the formally correct compare methods?
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.
The existing code makes some sense, since a common use case for accessibility is to use constants for them.
The pointer compare made more sense when (1) CPUs were way slower and (2) this was an in-house framework.
I agree we should change to use isEqualToString:
.
Also just below here, we don't need to explicitly copy the newAccessibilityLabel before passing it to initWithString:
. That initializer copies the contents ("initialized with the characters of aString
").
{ | ||
_bridge_prologue_write; | ||
{ _setAccessibilityToViewAndProperty(_accessibilityAttributedLabel, accessibilityAttributedLabel, accessibilityAttributedLabel, accessibilityAttributedLabel); } | ||
{ _setAccessibilityToViewAndProperty(_accessibilityLabel, accessibilityAttributedLabel.string, accessibilityLabel, accessibilityAttributedLabel.string); } |
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 looks a bit strange. Are attributed labels supposed to overwrite non-attributed ones? Since these attributed labels are still in beta, I guess we don't know yet?
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 is in fact the behaviour I'm observing. It's like UILabel's attributedText
and text
attributes, which override themselves (confirmed in Playground with XC9 GM).
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.
Cool by me then :)
Also, please update CHANGELOG and make sure CI builds. Thanks! |
🚫 CI failed with log |
@property (nonatomic, copy, nullable) NSString *accessibilityHint; | ||
@property (nullable, nonatomic, copy) NSAttributedString *accessibilityAttributedHint API_AVAILABLE(ios(11.0),tvos(11.0)); | ||
@property (nonatomic, copy, nullable) NSString *accessibilityValue; | ||
@property (nullable, nonatomic, copy) NSAttributedString *accessibilityAttributedValue API_AVAILABLE(ios(11.0),tvos(11.0)); |
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.
Please follow the (nonatomic, copy, nullable)
convention for changes in this file.
The CI Build fails can all be categorized in 2 errors in _ASPendingState.mm: I don't know how to resolve those issues. Which Xcode are you using on your CI server? |
🚫 CI failed with log |
@fruitcoder We're running Xcode 8. @garrettmoon and I agreed that we shouldn't upgrade to Xcode 9 until it's out of GM. And even so, using |
Totally understand, I‘ll update my code to run on XCode 8 on Monday |
Great. Thank you! |
I'm not too happy about the runtime code with |
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.
1 last iteration and this PR will be good to land!
@@ -901,6 +911,28 @@ - (void)setAccessibilityLabel:(NSString *)accessibilityLabel | |||
{ | |||
_bridge_prologue_write; | |||
_setAccessibilityToViewAndProperty(_accessibilityLabel, accessibilityLabel, accessibilityLabel, accessibilityLabel); | |||
if (AS_AT_LEAST_IOS11) { | |||
_accessibilityAttributedLabel = [[NSAttributedString alloc] initWithString:accessibilityLabel]; | |||
BOOL shouldApply = ASDisplayNodeShouldApplyBridgedWriteToView(self); |
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.
Use _setAttributedAccessibilityToViewAndProperty
here?
{ | ||
_bridge_prologue_write; | ||
{ _setAttributedAccessibilityToViewAndProperty(_accessibilityAttributedLabel, accessibilityAttributedLabel, @"accessibilityAttributedLabel", accessibilityAttributedLabel); } | ||
{ _setAttributedAccessibilityToViewAndProperty(_accessibilityLabel, accessibilityAttributedLabel.string, @"accessibilityLabel", accessibilityAttributedLabel.string); } |
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.
Shouldn't we use _setAccessibilityToViewAndProperty
for _accessibilityLabel
?
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.
Hm, I wonder if one of the tests should have caught that. But you're definitely right!
@@ -913,6 +945,22 @@ - (void)setAccessibilityHint:(NSString *)accessibilityHint | |||
{ | |||
_bridge_prologue_write; | |||
_setAccessibilityToViewAndProperty(_accessibilityHint, accessibilityHint, accessibilityHint, accessibilityHint); | |||
if (AS_AT_LEAST_IOS11) { | |||
_setAttributedAccessibilityToViewAndProperty(_accessibilityAttributedHint, [[NSAttributedString alloc] initWithString:accessibilityHint], @"accessibilityAttributedHint", [[NSAttributedString alloc] initWithString:accessibilityHint]); |
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.
Nit: For readability and a tiny perf win, cache [[NSAttributedString alloc] initWithString:accessibilityHint]
instead of allocating 2 identical objects.
{ | ||
_bridge_prologue_write; | ||
{ _setAttributedAccessibilityToViewAndProperty(_accessibilityAttributedHint, accessibilityAttributedHint, @"accessibilityAttributedHint", accessibilityAttributedHint); } | ||
{ _setAttributedAccessibilityToViewAndProperty(_accessibilityHint, accessibilityAttributedHint.string, @"accessibilityHint", accessibilityAttributedHint.string); } |
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.
Same as above, use _setAccessibilityToViewAndProperty
for _accessibilityHint
.
@@ -925,6 +973,22 @@ - (void)setAccessibilityValue:(NSString *)accessibilityValue | |||
{ | |||
_bridge_prologue_write; | |||
_setAccessibilityToViewAndProperty(_accessibilityValue, accessibilityValue, accessibilityValue, accessibilityValue); | |||
if (AS_AT_LEAST_IOS11) { | |||
_setAttributedAccessibilityToViewAndProperty(_accessibilityAttributedValue, [[NSAttributedString alloc] initWithString:accessibilityValue], @"accessibilityAttributedValue", [[NSAttributedString alloc] initWithString:accessibilityValue]); |
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.
Nit: Same here, cache the attributed string.
{ | ||
_bridge_prologue_write; | ||
{ _setAttributedAccessibilityToViewAndProperty(_accessibilityAttributedValue, accessibilityAttributedValue, @"accessibilityAttributedValue", accessibilityAttributedValue); } | ||
{ _setAttributedAccessibilityToViewAndProperty(_accessibilityValue, accessibilityAttributedValue.string, @"accessibilityValue", accessibilityAttributedValue.string); } |
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.
Use _setAccessibilityToViewAndProperty
.
@fruitcoder I think it's a good approach for the time being. These new macros are private so I wouldn't worry much about them being used without version checks. |
…yToViewAndProperty only for attributed properties.
Landing time 🛬 Thanks, @fruitcoder! |
…ted strings for them - Fix crashes caused by TextureGroup#554
…ccessibilityValue (TextureGroup#554) * Added attributed versions of accessibilityLabel, accessibilityHint and accessibilityValue * Follow conventions for property types * Use curly braces * Update changelog * Follow conventions for property types in UIView+ASConvenience.h * Add compatibility for Xcode 8 * Use isEqualToString instead of pointer comparison * Only allocate attributed strings once. Use _setAttributedAccessibilityToViewAndProperty only for attributed properties.
…allocating attributed strings for them #trivial (TextureGroup#581) * Make sure accessibility strings are not nil before allocating attributed strings for them - Fix crashes caused by TextureGroup#554 * Update tests
First version of how we might add attributed string functionality to accessibility labels, hints and values. The properties are only available from iOS 11 and tv 11 and up so I added
API_AVAILABLE
to the properties inASDisplayNode
.