|
6 | 6 | */ |
7 | 7 |
|
8 | 8 | #import "RCTViewComponentView.h" |
9 | | -#import "RCTViewAccessibilityElement.h" |
10 | 9 |
|
11 | 10 | #import <CoreGraphics/CoreGraphics.h> |
12 | 11 | #import <QuartzCore/QuartzCore.h> |
@@ -51,8 +50,6 @@ @implementation RCTViewComponentView { |
51 | 50 | UIView *_containerView; |
52 | 51 | BOOL _useCustomContainerView; |
53 | 52 | NSMutableSet<NSString *> *_accessibilityOrderNativeIDs; |
54 | | - NSMutableArray<NSObject *> *_accessibilityElements; |
55 | | - RCTViewAccessibilityElement *_axElementDescribingSelf; |
56 | 53 | } |
57 | 54 |
|
58 | 55 | #ifdef RCT_DYNAMIC_FRAMEWORKS |
@@ -405,7 +402,11 @@ - (void)updateProps:(const Props::Shared &)props oldProps:(const Props::Shared & |
405 | 402 | [_accessibilityOrderNativeIDs addObject:RCTNSStringFromString(childId)]; |
406 | 403 | } |
407 | 404 |
|
408 | | - _accessibilityElements = [NSMutableArray new]; |
| 405 | + // If we are prop updating and have children we can go ahead and assign this prop. |
| 406 | + // Otherwise, we might not have children attached yet and need to wait before then. |
| 407 | + if (self.currentContainerView.subviews.count > 0) { |
| 408 | + [self updateAccessibilityElements]; |
| 409 | + } |
409 | 410 | } |
410 | 411 |
|
411 | 412 | // `accessibilityTraits` |
@@ -617,7 +618,6 @@ - (void)prepareForRecycle |
617 | 618 | _isJSResponder = NO; |
618 | 619 | _removeClippedSubviews = NO; |
619 | 620 | _reactSubviews = [NSMutableArray new]; |
620 | | - _accessibilityElements = [NSMutableArray new]; |
621 | 621 | } |
622 | 622 |
|
623 | 623 | - (void)setPropKeysManagedByAnimated_DO_NOT_USE_THIS_IS_BROKEN:(NSSet<NSString *> *_Nullable)props |
@@ -1149,43 +1149,37 @@ - (NSObject *)accessibilityElement |
1149 | 1149 | return self; |
1150 | 1150 | } |
1151 | 1151 |
|
1152 | | -- (NSArray<NSObject *> *)accessibilityElements |
| 1152 | +- (void)didMoveToSuperview |
1153 | 1153 | { |
1154 | | - if ([_accessibilityOrderNativeIDs count] <= 0) { |
1155 | | - return super.accessibilityElements; |
| 1154 | + // At this point we are guaranteed to have subviews, if we are going to have them |
| 1155 | + if (ReactNativeFeatureFlags::enableAccessibilityOrder()) { |
| 1156 | + [self updateAccessibilityElements]; |
1156 | 1157 | } |
| 1158 | +} |
1157 | 1159 |
|
1158 | | - // TODO: Currently this ignores changes to descendant nativeID's. While that should rarely, if ever happen, it's an |
1159 | | - // edge case we should address. Currently this fixes some app deaths so landing this without addressing that edge case |
1160 | | - // for now. |
1161 | | - if ([_accessibilityElements count] > 0) { |
1162 | | - return _accessibilityElements; |
| 1160 | +- (void)updateAccessibilityElements |
| 1161 | +{ |
| 1162 | + if ([_accessibilityOrderNativeIDs count] == 0) { |
| 1163 | + self.accessibilityElements = nil; |
| 1164 | + return; |
1163 | 1165 | } |
1164 | 1166 |
|
1165 | 1167 | NSMutableDictionary<NSString *, UIView *> *nativeIdToView = [NSMutableDictionary new]; |
1166 | | - |
1167 | 1168 | [RCTViewComponentView collectAccessibilityElements:self |
1168 | 1169 | intoDictionary:nativeIdToView |
1169 | 1170 | nativeIds:_accessibilityOrderNativeIDs]; |
1170 | 1171 |
|
1171 | | - for (auto childId : _props->accessibilityOrder) { |
| 1172 | + NSMutableArray *accessibilityElements = [NSMutableArray new]; |
| 1173 | + for (const auto &childId : _props->accessibilityOrder) { |
1172 | 1174 | NSString *nsStringChildId = RCTNSStringFromString(childId); |
1173 | | - // Special case to allow for self-referencing with accessibilityOrder |
1174 | | - if ([nsStringChildId isEqualToString:self.nativeId]) { |
1175 | | - if (!_axElementDescribingSelf) { |
1176 | | - _axElementDescribingSelf = [[RCTViewAccessibilityElement alloc] initWithView:self]; |
1177 | | - } |
1178 | | - _axElementDescribingSelf.isAccessibilityElement = [super isAccessibilityElement]; |
1179 | | - [_accessibilityElements addObject:_axElementDescribingSelf]; |
1180 | | - } else { |
1181 | | - UIView *viewWithMatchingNativeId = [nativeIdToView objectForKey:nsStringChildId]; |
1182 | | - if (viewWithMatchingNativeId) { |
1183 | | - [_accessibilityElements addObject:viewWithMatchingNativeId]; |
1184 | | - } |
| 1175 | + |
| 1176 | + UIView *viewWithMatchingNativeId = [nativeIdToView objectForKey:nsStringChildId]; |
| 1177 | + if (viewWithMatchingNativeId != nil) { |
| 1178 | + [accessibilityElements addObject:viewWithMatchingNativeId]; |
1185 | 1179 | } |
1186 | 1180 | } |
1187 | 1181 |
|
1188 | | - return _accessibilityElements; |
| 1182 | + self.accessibilityElements = accessibilityElements; |
1189 | 1183 | } |
1190 | 1184 |
|
1191 | 1185 | + (void)collectAccessibilityElements:(UIView *)view |
@@ -1252,13 +1246,6 @@ - (BOOL)isAccessibilityElement |
1252 | 1246 | return self.contentView.isAccessibilityElement; |
1253 | 1247 | } |
1254 | 1248 |
|
1255 | | - // If we reference ourselves in accessibilityOrder then we will make a |
1256 | | - // UIAccessibilityElement object to represent ourselves since returning YES |
1257 | | - // here would mean iOS would not call into accessibilityElements |
1258 | | - if ([_accessibilityOrderNativeIDs containsObject:self.nativeId]) { |
1259 | | - return NO; |
1260 | | - } |
1261 | | - |
1262 | 1249 | return [super isAccessibilityElement]; |
1263 | 1250 | } |
1264 | 1251 |
|
|
0 commit comments