@lodev09/react-native-true-sheet 3.11.0-beta.13 → 3.11.0-beta.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -31,6 +31,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
31
31
|
@optional
|
|
32
32
|
|
|
33
33
|
- (void)containerViewHeaderDidChangeSize:(CGSize)newSize;
|
|
34
|
+
- (void)containerViewFooterDidChangeSize:(CGSize)newSize;
|
|
34
35
|
|
|
35
36
|
@end
|
|
36
37
|
|
|
@@ -71,6 +72,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
71
72
|
*/
|
|
72
73
|
- (void)layoutFooter;
|
|
73
74
|
|
|
75
|
+
- (BOOL)hasAccessibilityFooterElements;
|
|
76
|
+
|
|
74
77
|
/**
|
|
75
78
|
* Setup scrollable content
|
|
76
79
|
*/
|
|
@@ -88,11 +88,22 @@ using namespace facebook::react;
|
|
|
88
88
|
[elements addObject:_contentView];
|
|
89
89
|
}
|
|
90
90
|
if (_footerView) {
|
|
91
|
-
|
|
91
|
+
// Footer hosts are layout containers; expose their children when present so
|
|
92
|
+
// VoiceOver and XCTest can target the actual footer controls.
|
|
93
|
+
NSArray *footerElements = _footerView.accessibilityElements;
|
|
94
|
+
if (footerElements.count > 0) {
|
|
95
|
+
[elements addObjectsFromArray:footerElements];
|
|
96
|
+
} else {
|
|
97
|
+
[elements addObject:_footerView];
|
|
98
|
+
}
|
|
92
99
|
}
|
|
93
100
|
return elements;
|
|
94
101
|
}
|
|
95
102
|
|
|
103
|
+
- (BOOL)hasAccessibilityFooterElements {
|
|
104
|
+
return _footerView && _footerView.accessibilityElements.count > 0;
|
|
105
|
+
}
|
|
106
|
+
|
|
96
107
|
#pragma mark - Layout
|
|
97
108
|
|
|
98
109
|
- (void)layoutSubviews {
|
|
@@ -251,6 +262,7 @@ using namespace facebook::react;
|
|
|
251
262
|
#pragma mark - TrueSheetFooterViewDelegate
|
|
252
263
|
|
|
253
264
|
- (void)footerViewDidChangeSize:(CGSize)newSize {
|
|
265
|
+
[self.delegate containerViewFooterDidChangeSize:newSize];
|
|
254
266
|
if (@available(iOS 26.0, *)) {
|
|
255
267
|
[self setupEdgeInteractions];
|
|
256
268
|
}
|
|
@@ -53,13 +53,19 @@ using namespace facebook::react;
|
|
|
53
53
|
- (NSArray *)accessibilityElements {
|
|
54
54
|
NSMutableArray *elements = [NSMutableArray array];
|
|
55
55
|
[self collectAccessibilityElementsFromView:self into:elements];
|
|
56
|
-
|
|
56
|
+
if (elements.count > 0) {
|
|
57
|
+
return elements;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return [super accessibilityElements];
|
|
57
61
|
}
|
|
58
62
|
|
|
59
63
|
- (void)collectAccessibilityElementsFromView:(UIView *)view into:(NSMutableArray *)elements {
|
|
60
64
|
for (UIView *subview in view.subviews) {
|
|
61
65
|
if (subview.isAccessibilityElement || subview.accessibilityLabel || subview.accessibilityIdentifier) {
|
|
62
66
|
[elements addObject:subview];
|
|
67
|
+
} else if (subview.accessibilityElements.count > 0) {
|
|
68
|
+
[elements addObjectsFromArray:subview.accessibilityElements];
|
|
63
69
|
} else {
|
|
64
70
|
[self collectAccessibilityElementsFromView:subview into:elements];
|
|
65
71
|
}
|
package/ios/TrueSheetView.mm
CHANGED
|
@@ -573,6 +573,10 @@ using namespace facebook::react;
|
|
|
573
573
|
[self setupSheetDetentsForSizeChange];
|
|
574
574
|
}
|
|
575
575
|
|
|
576
|
+
- (void)containerViewFooterDidChangeSize:(CGSize)newSize {
|
|
577
|
+
[_controller setupAccessibilityContainer];
|
|
578
|
+
}
|
|
579
|
+
|
|
576
580
|
// When the ScrollView changes (e.g. conditional remount), re-pin the new ScrollView.
|
|
577
581
|
- (void)containerViewScrollViewDidChange {
|
|
578
582
|
[self setupScrollable];
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
//
|
|
8
8
|
|
|
9
9
|
#import "TrueSheetViewController.h"
|
|
10
|
+
#import "TrueSheetContainerView.h"
|
|
10
11
|
#import "TrueSheetContentView.h"
|
|
11
12
|
#import "core/TrueSheetBlurView.h"
|
|
12
13
|
#import "core/TrueSheetDetentCalculator.h"
|
|
@@ -18,6 +19,7 @@
|
|
|
18
19
|
|
|
19
20
|
#import <React/RCTLog.h>
|
|
20
21
|
#import <React/RCTScrollViewComponentView.h>
|
|
22
|
+
#import <objc/runtime.h>
|
|
21
23
|
#import <react/renderer/components/TrueSheetSpec/Props.h>
|
|
22
24
|
|
|
23
25
|
using namespace facebook::react;
|
|
@@ -32,8 +34,14 @@ static BOOL TrueSheetPositionStateEquals(TrueSheetPositionState a, TrueSheetPosi
|
|
|
32
34
|
return fabs(a.position - b.position) <= 0.01 && fabs(a.detent - b.detent) <= 0.01 && fabs(a.index - b.index) <= 0.01;
|
|
33
35
|
}
|
|
34
36
|
|
|
37
|
+
static char TrueSheetAccessibilityWindowOwnerKey;
|
|
38
|
+
static char TrueSheetAccessibilityWindowPreviousElementsKey;
|
|
39
|
+
|
|
35
40
|
@interface TrueSheetViewController ()
|
|
36
41
|
|
|
42
|
+
- (UIViewController *)accessibilityPresentingViewController;
|
|
43
|
+
- (void)restoreWindowAccessibilityElements;
|
|
44
|
+
- (void)setSheetAccessibilityElementsHidden:(BOOL)hidden;
|
|
37
45
|
- (void)setAccessibilityContentElement:(UIView *)contentView;
|
|
38
46
|
|
|
39
47
|
@end
|
|
@@ -57,6 +65,8 @@ static BOOL TrueSheetPositionStateEquals(TrueSheetPositionState a, TrueSheetPosi
|
|
|
57
65
|
|
|
58
66
|
UIView *_anchorView;
|
|
59
67
|
|
|
68
|
+
__weak UIWindow *_accessibilityWindow;
|
|
69
|
+
|
|
60
70
|
TrueSheetBlurView *_blurView;
|
|
61
71
|
TrueSheetGrabberView *_grabberView;
|
|
62
72
|
TrueSheetDetentCalculator *_detentCalculator;
|
|
@@ -97,6 +107,7 @@ static BOOL TrueSheetPositionStateEquals(TrueSheetPositionState a, TrueSheetPosi
|
|
|
97
107
|
}
|
|
98
108
|
|
|
99
109
|
- (void)dealloc {
|
|
110
|
+
[self restoreWindowAccessibilityElements];
|
|
100
111
|
[_transitioningTimer invalidate];
|
|
101
112
|
_transitioningTimer = nil;
|
|
102
113
|
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
|
@@ -227,6 +238,7 @@ static BOOL TrueSheetPositionStateEquals(TrueSheetPositionState a, TrueSheetPosi
|
|
|
227
238
|
|
|
228
239
|
- (void)viewDidAppear:(BOOL)animated {
|
|
229
240
|
[super viewDidAppear:animated];
|
|
241
|
+
[self setSheetAccessibilityElementsHidden:NO];
|
|
230
242
|
|
|
231
243
|
if (!_isPresented) {
|
|
232
244
|
[_parentSheetController.delegate viewControllerDidBlur];
|
|
@@ -244,9 +256,10 @@ static BOOL TrueSheetPositionStateEquals(TrueSheetPositionState a, TrueSheetPosi
|
|
|
244
256
|
});
|
|
245
257
|
|
|
246
258
|
[self setupGestureRecognizer];
|
|
247
|
-
[self setupAccessibilityContainer];
|
|
248
259
|
_isPresented = YES;
|
|
249
260
|
}
|
|
261
|
+
|
|
262
|
+
[self setupAccessibilityContainer];
|
|
250
263
|
}
|
|
251
264
|
|
|
252
265
|
- (void)setupAccessibilityContainer {
|
|
@@ -258,17 +271,82 @@ static BOOL TrueSheetPositionStateEquals(TrueSheetPositionState a, TrueSheetPosi
|
|
|
258
271
|
[self setAccessibilityContentElement:contentView];
|
|
259
272
|
}
|
|
260
273
|
|
|
274
|
+
- (UIViewController *)accessibilityPresentingViewController {
|
|
275
|
+
UIViewController *presentingViewController = self.presentingViewController;
|
|
276
|
+
while ([presentingViewController isKindOfClass:[TrueSheetViewController class]] &&
|
|
277
|
+
presentingViewController.presentingViewController) {
|
|
278
|
+
presentingViewController = presentingViewController.presentingViewController;
|
|
279
|
+
}
|
|
280
|
+
return presentingViewController;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
- (void)restoreWindowAccessibilityElements {
|
|
284
|
+
UIWindow *window = _accessibilityWindow;
|
|
285
|
+
if (window) {
|
|
286
|
+
// The active sheet may temporarily own window accessibility traversal. Only
|
|
287
|
+
// restore the previous value when this controller still owns that override.
|
|
288
|
+
NSValue *ownerValue = objc_getAssociatedObject(window, &TrueSheetAccessibilityWindowOwnerKey);
|
|
289
|
+
if (ownerValue && ownerValue.nonretainedObjectValue == self) {
|
|
290
|
+
id previousElements = objc_getAssociatedObject(window, &TrueSheetAccessibilityWindowPreviousElementsKey);
|
|
291
|
+
window.accessibilityElements = previousElements == [NSNull null] ? nil : previousElements;
|
|
292
|
+
objc_setAssociatedObject(window, &TrueSheetAccessibilityWindowOwnerKey, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
|
293
|
+
objc_setAssociatedObject(
|
|
294
|
+
window, &TrueSheetAccessibilityWindowPreviousElementsKey, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
_accessibilityWindow = nil;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
- (void)setSheetAccessibilityElementsHidden:(BOOL)hidden {
|
|
302
|
+
self.view.accessibilityElementsHidden = hidden;
|
|
303
|
+
|
|
304
|
+
UIView *presentedView = self.presentationController.presentedView;
|
|
305
|
+
if (presentedView) {
|
|
306
|
+
presentedView.accessibilityElementsHidden = hidden;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
261
310
|
- (void)setAccessibilityContentElement:(UIView *)contentView {
|
|
311
|
+
NSArray *contentElements = contentView.accessibilityElements;
|
|
312
|
+
NSArray *accessibilityElements = contentElements.count > 0 ? contentElements : @[ contentView ];
|
|
313
|
+
BOOL hasAccessibilityFooterElements = [contentView isKindOfClass:[TrueSheetContainerView class]] &&
|
|
314
|
+
[(TrueSheetContainerView *)contentView hasAccessibilityFooterElements];
|
|
315
|
+
// Footer controls exposed as separate accessibility elements can be skipped
|
|
316
|
+
// by XCTest when the presented sheet is a hard modal accessibility boundary.
|
|
317
|
+
BOOL isAccessibilityModal = _dimmed && !hasAccessibilityFooterElements;
|
|
318
|
+
|
|
262
319
|
self.view.isAccessibilityElement = NO;
|
|
263
320
|
self.view.accessibilityViewIsModal = YES;
|
|
264
|
-
self.view.accessibilityElements =
|
|
321
|
+
self.view.accessibilityElements = accessibilityElements;
|
|
265
322
|
|
|
266
323
|
UIView *presentedView = self.presentationController.presentedView;
|
|
267
324
|
if (presentedView) {
|
|
268
325
|
presentedView.isAccessibilityElement = NO;
|
|
269
|
-
presentedView.accessibilityViewIsModal =
|
|
270
|
-
presentedView.accessibilityElements =
|
|
326
|
+
presentedView.accessibilityViewIsModal = isAccessibilityModal;
|
|
327
|
+
presentedView.accessibilityElements = accessibilityElements;
|
|
328
|
+
|
|
329
|
+
UIWindow *window = self.view.window;
|
|
330
|
+
UIViewController *presentingViewController = [self accessibilityPresentingViewController];
|
|
331
|
+
if (window && presentingViewController.view) {
|
|
332
|
+
if (!_accessibilityWindow) {
|
|
333
|
+
_accessibilityWindow = window;
|
|
334
|
+
id previousElements = objc_getAssociatedObject(window, &TrueSheetAccessibilityWindowPreviousElementsKey);
|
|
335
|
+
if (!previousElements) {
|
|
336
|
+
previousElements = window.accessibilityElements ?: [NSNull null];
|
|
337
|
+
objc_setAssociatedObject(window, &TrueSheetAccessibilityWindowPreviousElementsKey, previousElements,
|
|
338
|
+
OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
objc_setAssociatedObject(window, &TrueSheetAccessibilityWindowOwnerKey, [NSValue valueWithNonretainedObject:self],
|
|
342
|
+
OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
|
343
|
+
window.accessibilityElements =
|
|
344
|
+
isAccessibilityModal ? @[ presentedView ] : @[ presentingViewController.view, presentedView ];
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
271
347
|
}
|
|
348
|
+
|
|
349
|
+
[self restoreWindowAccessibilityElements];
|
|
272
350
|
}
|
|
273
351
|
|
|
274
352
|
- (void)emitWillDismissEvents {
|
|
@@ -283,6 +361,7 @@ static BOOL TrueSheetPositionStateEquals(TrueSheetPositionState a, TrueSheetPosi
|
|
|
283
361
|
|
|
284
362
|
- (void)emitDidDismissEvents {
|
|
285
363
|
if (self.isBeingDismissed) {
|
|
364
|
+
[self restoreWindowAccessibilityElements];
|
|
286
365
|
_isPresented = NO;
|
|
287
366
|
_isWillDismissEmitted = NO;
|
|
288
367
|
|
|
@@ -290,6 +369,7 @@ static BOOL TrueSheetPositionStateEquals(TrueSheetPositionState a, TrueSheetPosi
|
|
|
290
369
|
_anchorView = nil;
|
|
291
370
|
|
|
292
371
|
[_parentSheetController.delegate viewControllerDidFocus];
|
|
372
|
+
[_parentSheetController setSheetAccessibilityElementsHidden:NO];
|
|
293
373
|
[_parentSheetController setupAccessibilityContainer];
|
|
294
374
|
_parentSheetController = nil;
|
|
295
375
|
|
|
@@ -300,6 +380,8 @@ static BOOL TrueSheetPositionStateEquals(TrueSheetPositionState a, TrueSheetPosi
|
|
|
300
380
|
|
|
301
381
|
- (void)viewWillDisappear:(BOOL)animated {
|
|
302
382
|
[super viewWillDisappear:animated];
|
|
383
|
+
[self restoreWindowAccessibilityElements];
|
|
384
|
+
[self setSheetAccessibilityElementsHidden:YES];
|
|
303
385
|
|
|
304
386
|
// Dispatch to allow pan gesture to set _isDragging before checking
|
|
305
387
|
// handleTransitionTracker will emit when sheet is transitioning to dismiss
|
package/package.json
CHANGED