@onekeyfe/react-native-pager-view 3.0.179-alpha.2026101503 → 3.0.179-alpha.302
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.
- package/android/src/main/java/com/reactnativepagerview/CollapsiblePagerViewManager.kt +0 -10
- package/android/src/main/java/com/reactnativepagerview/NativeScrollerViewManager.kt +0 -4
- package/docs/SPEC.md +1 -77
- package/ios/RNCCollapsiblePagerViewComponentView.mm +138 -838
- package/ios/RNCNativeScrollerComponentView.mm +38 -93
- package/ios/RNCPagerViewComponentView.h +0 -7
- package/ios/RNCPagerViewComponentView.mm +0 -34
- package/ios/tests/RNCCollapsiblePagerHitTestTests.mm +0 -49
- package/lib/module/CollapsiblePagerView.js +1 -27
- package/lib/module/CollapsiblePagerView.web.js +0 -4
- package/lib/module/CollapsiblePagerViewNativeComponent.ts +0 -6
- package/lib/module/NativeScroller.js +82 -105
- package/lib/module/NativeScroller.web.js +0 -2
- package/lib/module/NativeScrollerNativeComponent.ts +0 -2
- package/lib/typescript/src/CollapsiblePagerView.d.ts +1 -10
- package/lib/typescript/src/CollapsiblePagerView.web.d.ts +0 -4
- package/lib/typescript/src/CollapsiblePagerViewNativeComponent.d.ts +0 -8
- package/lib/typescript/src/NativeScroller.d.ts +0 -4
- package/lib/typescript/src/NativeScrollerNativeComponent.d.ts +0 -2
- package/package.json +2 -2
- package/src/CollapsiblePagerView.tsx +0 -44
- package/src/CollapsiblePagerView.web.tsx +0 -8
- package/src/CollapsiblePagerViewNativeComponent.ts +0 -6
- package/src/NativeScroller.tsx +2 -27
- package/src/NativeScroller.web.tsx +0 -2
- package/src/NativeScrollerNativeComponent.ts +0 -2
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
#import "RNCCollapsiblePagerViewComponentView.h"
|
|
2
|
-
#import "RNCPagerViewComponentView.h"
|
|
3
2
|
#import "RNCNativeScrollerComponentView.h"
|
|
4
3
|
#import "RNCCollapsiblePagerReleasedStatePolicy.h"
|
|
5
4
|
|
|
@@ -195,23 +194,6 @@ static BOOL RNCIsEnabledHorizontalScrollOwner(UIScrollView *scroll)
|
|
|
195
194
|
scroll.contentSize.height <= CGRectGetHeight(scroll.bounds) + 0.5;
|
|
196
195
|
}
|
|
197
196
|
|
|
198
|
-
static UIScrollView *RNCNestedOuterReactPagerScrollView(UIView *view)
|
|
199
|
-
{
|
|
200
|
-
Class outerPagerClass = NSClassFromString(@"RNCPagerViewComponentView");
|
|
201
|
-
if (outerPagerClass == Nil) return nil;
|
|
202
|
-
UIScrollView *pagingAncestor = nil;
|
|
203
|
-
for (UIView *ancestor = view.superview; ancestor != nil; ancestor = ancestor.superview) {
|
|
204
|
-
if ([ancestor isKindOfClass:UIScrollView.class] &&
|
|
205
|
-
((UIScrollView *)ancestor).pagingEnabled) {
|
|
206
|
-
pagingAncestor = (UIScrollView *)ancestor;
|
|
207
|
-
}
|
|
208
|
-
if ([ancestor isKindOfClass:outerPagerClass]) {
|
|
209
|
-
return pagingAncestor.panGestureRecognizer.enabled ? pagingAncestor : nil;
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
return nil;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
197
|
static void RNCGuardNestedHorizontalPans(UIView *view, UIGestureRecognizer *guard)
|
|
216
198
|
{
|
|
217
199
|
if ([view isKindOfClass:UIScrollView.class]) {
|
|
@@ -237,7 +219,6 @@ static void RNCCollapsiblePagerLog(NSString *message)
|
|
|
237
219
|
logFunction(logClass, selector, @"CollapsiblePager", message);
|
|
238
220
|
}
|
|
239
221
|
|
|
240
|
-
|
|
241
222
|
static BOOL RNCGetColorComponents(UIColor *color, UITraitCollection *traits,
|
|
242
223
|
CGFloat *red, CGFloat *green, CGFloat *blue, CGFloat *alpha)
|
|
243
224
|
{
|
|
@@ -1061,9 +1042,7 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
1061
1042
|
CGFloat maximum = MAX(0, inner.contentSize.width - CGRectGetWidth(inner.bounds));
|
|
1062
1043
|
BOOL canScroll = maximum > 0 && (intent.x < 0
|
|
1063
1044
|
? inner.contentOffset.x < maximum - 0.5 : inner.contentOffset.x > 0.5);
|
|
1064
|
-
if (canScroll)
|
|
1065
|
-
return NO;
|
|
1066
|
-
}
|
|
1045
|
+
if (canScroll) return NO;
|
|
1067
1046
|
}
|
|
1068
1047
|
}
|
|
1069
1048
|
if (gestureRecognizer == self.panGestureRecognizer && self.excludedHeaderView != nil) {
|
|
@@ -1073,8 +1052,7 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
1073
1052
|
return NO;
|
|
1074
1053
|
}
|
|
1075
1054
|
}
|
|
1076
|
-
|
|
1077
|
-
return result;
|
|
1055
|
+
return [super gestureRecognizerShouldBegin:gestureRecognizer];
|
|
1078
1056
|
}
|
|
1079
1057
|
|
|
1080
1058
|
@end
|
|
@@ -1263,8 +1241,6 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
1263
1241
|
|
|
1264
1242
|
@interface RNCCollapsiblePagerOuterPagerPanGestureRecognizer : UIPanGestureRecognizer
|
|
1265
1243
|
@property (nonatomic, strong) NSHashTable<UIGestureRecognizer *> *blockedPagerGestures;
|
|
1266
|
-
@property (nonatomic, weak) UITouch *trackedTouch;
|
|
1267
|
-
@property (nonatomic, assign) BOOL protectsNestedBody;
|
|
1268
1244
|
@end
|
|
1269
1245
|
|
|
1270
1246
|
@implementation RNCCollapsiblePagerOuterPagerPanGestureRecognizer
|
|
@@ -1289,14 +1265,6 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
1289
1265
|
return NO;
|
|
1290
1266
|
}
|
|
1291
1267
|
|
|
1292
|
-
- (void)reset
|
|
1293
|
-
{
|
|
1294
|
-
[super reset];
|
|
1295
|
-
self.trackedTouch = nil;
|
|
1296
|
-
self.protectsNestedBody = NO;
|
|
1297
|
-
self.cancelsTouchesInView = YES;
|
|
1298
|
-
}
|
|
1299
|
-
|
|
1300
1268
|
@end
|
|
1301
1269
|
|
|
1302
1270
|
@interface RNCCollapsiblePagerVerticalPagerGuardGestureRecognizer : UIGestureRecognizer
|
|
@@ -1440,8 +1408,7 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
1440
1408
|
UIScrollViewDelegate,
|
|
1441
1409
|
UIGestureRecognizerDelegate,
|
|
1442
1410
|
RCTMountingTransactionObserving,
|
|
1443
|
-
RNCNativeScrollerInsetCoordinator
|
|
1444
|
-
RNCPagerViewNestedOverlayObserver
|
|
1411
|
+
RNCNativeScrollerInsetCoordinator
|
|
1445
1412
|
>
|
|
1446
1413
|
- (void)finishPagerScrollEmittingSelection:(BOOL)emitSelection;
|
|
1447
1414
|
- (void)completeTransitionOnNextRunLoopForGeneration:(NSUInteger)generation
|
|
@@ -1451,8 +1418,6 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
1451
1418
|
- (void)liftSharedHeadersForPagerTransition:(NSString *)reason;
|
|
1452
1419
|
- (void)restoreSharedHeadersToContainer;
|
|
1453
1420
|
- (void)layoutSharedHeaders;
|
|
1454
|
-
- (void)restorePinnedStickyHeader;
|
|
1455
|
-
- (void)updatePinnedStickyHeader;
|
|
1456
1421
|
- (UIScrollView *)currentVerticalScrollViewForParentPager;
|
|
1457
1422
|
- (UIScrollView *)verticalScrollViewForPageAtIndex:(NSInteger)pageIndex;
|
|
1458
1423
|
- (UIScrollView *)findExplicitNativeScrollerInView:(UIView *)view;
|
|
@@ -1464,32 +1429,19 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
1464
1429
|
- (void)detachSharedHeaderPressCancellationGesture;
|
|
1465
1430
|
- (void)updateRefreshControlForScrollView:(UIScrollView *)scrollView;
|
|
1466
1431
|
- (void)releaseRefreshControlForScrollView:(UIScrollView *)scrollView;
|
|
1467
|
-
- (void)cancelTopInsetReboundCheck;
|
|
1468
|
-
- (void)scheduleTopInsetReboundCheck;
|
|
1469
|
-
- (void)syncScrollEdgeAppearance;
|
|
1470
|
-
- (void)updateScrollEdgeContentMasks;
|
|
1471
|
-
- (void)restoreScrollEdgeContentMasks;
|
|
1472
1432
|
- (void)sharedHeaderPressCancellationGestureChanged:(UIPanGestureRecognizer *)recognizer;
|
|
1473
1433
|
- (void)outerPagerGestureChanged:(UIPanGestureRecognizer *)recognizer;
|
|
1474
1434
|
- (void)verticalPagerGuardGestureChanged:(UIPanGestureRecognizer *)recognizer;
|
|
1475
1435
|
- (void)connectVerticalPagerGuard;
|
|
1476
1436
|
- (void)observedListPanChanged:(UIPanGestureRecognizer *)recognizer;
|
|
1477
|
-
- (BOOL)resolveExternalTopOverlay;
|
|
1478
|
-
- (void)registerExternalOuterPager;
|
|
1479
|
-
- (CGFloat)effectiveTopOverlayHeight;
|
|
1480
|
-
- (BOOL)hasFixedTopOverlay;
|
|
1481
1437
|
@end
|
|
1482
1438
|
|
|
1483
1439
|
@implementation RNCCollapsiblePagerViewComponentView {
|
|
1440
|
+
#if DEBUG
|
|
1441
|
+
NSUInteger _offsetDiagSequence;
|
|
1442
|
+
#endif
|
|
1484
1443
|
UIView *_containerView;
|
|
1485
1444
|
RNCCollapsiblePagerSharedHeaderView *_sharedHeaderHostView;
|
|
1486
|
-
UIView *_pinnedStickyHostView;
|
|
1487
|
-
BOOL _stickyHeaderIsPinned;
|
|
1488
|
-
UIView *_sharedHeaderMaskView;
|
|
1489
|
-
UIView *_originalSharedHeaderMaskView;
|
|
1490
|
-
NSMapTable<UIView *, id> *_originalPageMasks;
|
|
1491
|
-
NSMapTable<UIView *, UIView *> *_ownedPageMasks;
|
|
1492
|
-
CGFloat _pageMaskBoundary;
|
|
1493
1445
|
UIPageViewController *_pageViewController;
|
|
1494
1446
|
UIScrollView *_pageViewControllerScrollView;
|
|
1495
1447
|
UIScrollView *_pagerScrollView;
|
|
@@ -1497,16 +1449,6 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
1497
1449
|
NSMutableArray<UIViewController *> *_pageControllers;
|
|
1498
1450
|
UIView *_headerView;
|
|
1499
1451
|
UIView *_stickyHeaderView;
|
|
1500
|
-
UIView *_topOverlayView;
|
|
1501
|
-
UIView *_topOverlayHostView;
|
|
1502
|
-
UIScrollEdgeElementContainerInteraction *_topEdgeInteraction;
|
|
1503
|
-
UIScrollEdgeElementContainerInteraction *_stickyEdgeInteraction;
|
|
1504
|
-
UILabel *_topEdgeMarker;
|
|
1505
|
-
UILabel *_stickyEdgeMarker;
|
|
1506
|
-
__weak UIView *_topEdgeInteractionHost;
|
|
1507
|
-
__weak UIView *_stickyEdgeInteractionHost;
|
|
1508
|
-
__weak UIScrollView *_topEdgeScrollView;
|
|
1509
|
-
UIScrollEdgeEffectStyle *_originalTopEdgeStyle;
|
|
1510
1452
|
RNCCollapsiblePagerNativeTabBarView *_nativeTabBarView;
|
|
1511
1453
|
RNCCollapsiblePagerNativeSubHeaderView *_nativeSubHeaderView;
|
|
1512
1454
|
NSInteger _currentIndex;
|
|
@@ -1514,22 +1456,6 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
1514
1456
|
NSInteger _pendingInitialPage;
|
|
1515
1457
|
NSInteger _headerHeight;
|
|
1516
1458
|
NSInteger _stickyHeaderHeight;
|
|
1517
|
-
CGFloat _topOverlayHeight;
|
|
1518
|
-
NSInteger _externalTopOverlayTag;
|
|
1519
|
-
__weak UIView *_externalTopOverlayView;
|
|
1520
|
-
CGFloat _externalTopOverlayHeight;
|
|
1521
|
-
__weak RNCPagerViewComponentView *_externalOuterPager;
|
|
1522
|
-
BOOL _externalOuterPageActive;
|
|
1523
|
-
BOOL _externalOuterTransitioning;
|
|
1524
|
-
BOOL _topScrollEdgeHard;
|
|
1525
|
-
NSString *_topOverlayColorScheme;
|
|
1526
|
-
BOOL _pendingTopOverlayAppearanceCommit;
|
|
1527
|
-
BOOL _applyingTopOverlayInsetChange;
|
|
1528
|
-
BOOL _correctingTopInsetRebound;
|
|
1529
|
-
__weak UIScrollView *_pendingTopInsetReboundScrollView;
|
|
1530
|
-
NSString *_pendingTopInsetReboundPageKey;
|
|
1531
|
-
NSUInteger _pendingTopInsetReboundGeneration;
|
|
1532
|
-
NSTimer *_topInsetReboundTimer;
|
|
1533
1459
|
CGFloat _nativeTabBarHeight;
|
|
1534
1460
|
CGFloat _nativeSubHeaderHeight;
|
|
1535
1461
|
CGFloat _headerOffset;
|
|
@@ -1549,7 +1475,6 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
1549
1475
|
NSInteger _pendingGoToIndex;
|
|
1550
1476
|
BOOL _pendingGoToAnimated;
|
|
1551
1477
|
BOOL _needsSlotRebuild;
|
|
1552
|
-
BOOL _deferTopEdgeSlotRebuild;
|
|
1553
1478
|
BOOL _hasAppliedInitialPage;
|
|
1554
1479
|
BOOL _needsPropsReapply;
|
|
1555
1480
|
NSString *_layoutDirection;
|
|
@@ -1587,6 +1512,9 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
1587
1512
|
NSUInteger _observedPageGeneration;
|
|
1588
1513
|
NSDictionary<NSString *, NSNumber *> *_transitionPageOffsets;
|
|
1589
1514
|
NSMutableIndexSet *_transitionCompensatedPages;
|
|
1515
|
+
#if DEBUG
|
|
1516
|
+
NSInteger _transitionDiagBucket;
|
|
1517
|
+
#endif
|
|
1590
1518
|
NSInteger _transitionSourceIndex;
|
|
1591
1519
|
BOOL _syntheticPageRestore;
|
|
1592
1520
|
BOOL _headerSettledAtTop;
|
|
@@ -1652,8 +1580,6 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
1652
1580
|
_originalAlwaysBounceVertical = [NSMapTable weakToStrongObjectsMapTable];
|
|
1653
1581
|
_originalDirectionalLockEnabled = [NSMapTable weakToStrongObjectsMapTable];
|
|
1654
1582
|
_originalInsetAdjustmentBehavior = [NSMapTable weakToStrongObjectsMapTable];
|
|
1655
|
-
_originalPageMasks = [NSMapTable strongToStrongObjectsMapTable];
|
|
1656
|
-
_ownedPageMasks = [NSMapTable strongToStrongObjectsMapTable];
|
|
1657
1583
|
_pageKeys = @[];
|
|
1658
1584
|
_retainedPages = @"[]";
|
|
1659
1585
|
_currentIndex = 0;
|
|
@@ -1681,12 +1607,6 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
1681
1607
|
_sharedHeaderHostView = [RNCCollapsiblePagerSharedHeaderView new];
|
|
1682
1608
|
_sharedHeaderHostView.clipsToBounds = NO;
|
|
1683
1609
|
[_containerView addSubview:_sharedHeaderHostView];
|
|
1684
|
-
_pinnedStickyHostView = [UIView new];
|
|
1685
|
-
_pinnedStickyHostView.hidden = YES;
|
|
1686
|
-
[_containerView addSubview:_pinnedStickyHostView];
|
|
1687
|
-
_topOverlayHostView = [UIView new];
|
|
1688
|
-
_topOverlayHostView.hidden = YES;
|
|
1689
|
-
[_containerView addSubview:_topOverlayHostView];
|
|
1690
1610
|
|
|
1691
1611
|
_verticalPagerGesture =
|
|
1692
1612
|
[[RNCCollapsiblePagerVerticalPagerGuardGestureRecognizer alloc]
|
|
@@ -1744,39 +1664,14 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
1744
1664
|
viewProps.pointerEvents == PointerEventsMode::BoxOnly) {
|
|
1745
1665
|
return [super hitTest:point withEvent:event];
|
|
1746
1666
|
}
|
|
1747
|
-
if (_topOverlayView != nil) {
|
|
1748
|
-
CGPoint overlayPoint = [_topOverlayView convertPoint:point fromView:self];
|
|
1749
|
-
UIView *overlayHitView = [_topOverlayView hitTest:overlayPoint withEvent:event];
|
|
1750
|
-
if (overlayHitView != nil) return overlayHitView;
|
|
1751
|
-
}
|
|
1752
|
-
if (_stickyHeaderIsPinned) {
|
|
1753
|
-
CGPoint stickyPoint = [_pinnedStickyHostView convertPoint:point fromView:self];
|
|
1754
|
-
UIView *stickyHitView = [_pinnedStickyHostView hitTest:stickyPoint withEvent:event];
|
|
1755
|
-
if (stickyHitView != nil) return stickyHitView;
|
|
1756
|
-
}
|
|
1757
|
-
CGPoint headerPoint = [_sharedHeaderHostView convertPoint:point fromView:self];
|
|
1758
|
-
BOOL sharedHeaderPointIsVisible =
|
|
1759
|
-
_sharedHeaderHostView.maskView != _sharedHeaderMaskView ||
|
|
1760
|
-
_sharedHeaderMaskView == nil ||
|
|
1761
|
-
CGRectContainsPoint(_sharedHeaderMaskView.frame, headerPoint);
|
|
1762
1667
|
if (_nativeSmoothHeaderScrollEnabled && !_isBeingRecycled &&
|
|
1763
|
-
_sharedHeaderHostView.superview != _containerView
|
|
1764
|
-
|
|
1668
|
+
_sharedHeaderHostView.superview != _containerView) {
|
|
1669
|
+
CGPoint headerPoint = [_sharedHeaderHostView convertPoint:point fromView:self];
|
|
1765
1670
|
UIView *headerHitView =
|
|
1766
1671
|
[_sharedHeaderHostView hitTest:headerPoint withEvent:event];
|
|
1767
1672
|
if (headerHitView != nil) return headerHitView;
|
|
1768
1673
|
}
|
|
1769
|
-
|
|
1770
|
-
if (hitView != nil && !sharedHeaderPointIsVisible &&
|
|
1771
|
-
(hitView == _sharedHeaderHostView ||
|
|
1772
|
-
[hitView isDescendantOfView:_sharedHeaderHostView])) return nil;
|
|
1773
|
-
if (hitView != nil && _ownedPageMasks.count > 0 &&
|
|
1774
|
-
[_containerView convertPoint:point fromView:self].y < _pageMaskBoundary) {
|
|
1775
|
-
for (UIView *page in _ownedPageMasks.keyEnumerator.allObjects) {
|
|
1776
|
-
if ([hitView isDescendantOfView:page]) return nil;
|
|
1777
|
-
}
|
|
1778
|
-
}
|
|
1779
|
-
return hitView;
|
|
1674
|
+
return [super hitTest:point withEvent:event];
|
|
1780
1675
|
}
|
|
1781
1676
|
|
|
1782
1677
|
- (void)willMoveToSuperview:(UIView *)newSuperview
|
|
@@ -1791,18 +1686,11 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
1791
1686
|
- (void)didMoveToWindow
|
|
1792
1687
|
{
|
|
1793
1688
|
[super didMoveToWindow];
|
|
1794
|
-
[self registerExternalOuterPager];
|
|
1795
|
-
BOOL externalHeightChanged = [self resolveExternalTopOverlay];
|
|
1796
|
-
if (self.window == nil) [self restoreScrollEdgeContentMasks];
|
|
1797
|
-
[self syncScrollEdgeAppearance];
|
|
1798
|
-
[self emitTopScrollEdgeCapability];
|
|
1799
|
-
[self updateTopScrollEdgeForScrollView:_observedScrollView];
|
|
1800
1689
|
[self updateSharedHeaderPressCancellationGesture];
|
|
1801
1690
|
[self updateHeaderSettledStateForceBusy:NO];
|
|
1802
1691
|
for (UIScrollView *scrollView in _originalInsets.keyEnumerator) {
|
|
1803
|
-
[self updateNativeScrollerViewport:scrollView stickyHeight:self.window == nil ? 0 : _stickyHeaderHeight
|
|
1692
|
+
[self updateNativeScrollerViewport:scrollView stickyHeight:self.window == nil ? 0 : _stickyHeaderHeight];
|
|
1804
1693
|
}
|
|
1805
|
-
if (externalHeightChanged) [self reapplyInsetsToObservedScrollView];
|
|
1806
1694
|
// OneKey patch: removing a decelerating page from its window can suppress
|
|
1807
1695
|
// UIKit's final scroll callback. Restore the last acknowledged page on reattach.
|
|
1808
1696
|
if (self.window != nil && _isPagerDragging &&
|
|
@@ -1824,320 +1712,8 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
1824
1712
|
}
|
|
1825
1713
|
}
|
|
1826
1714
|
|
|
1827
|
-
- (CGFloat)effectiveTopOverlayHeight
|
|
1828
|
-
{
|
|
1829
|
-
return _topOverlayView != nil ? _topOverlayHeight : _externalTopOverlayHeight;
|
|
1830
|
-
}
|
|
1831
|
-
|
|
1832
|
-
- (BOOL)hasFixedTopOverlay
|
|
1833
|
-
{
|
|
1834
|
-
return _topOverlayView != nil ||
|
|
1835
|
-
(_externalTopOverlayTag > 0 && _externalTopOverlayHeight > 0);
|
|
1836
|
-
}
|
|
1837
|
-
|
|
1838
|
-
- (void)registerExternalOuterPager
|
|
1839
|
-
{
|
|
1840
|
-
RNCPagerViewComponentView *outer = nil;
|
|
1841
|
-
if (_externalTopOverlayTag > 0 && self.window != nil && !_isBeingRecycled) {
|
|
1842
|
-
for (UIView *ancestor = self.superview; ancestor != nil; ancestor = ancestor.superview) {
|
|
1843
|
-
if ([ancestor isKindOfClass:RNCPagerViewComponentView.class]) {
|
|
1844
|
-
outer = (RNCPagerViewComponentView *)ancestor;
|
|
1845
|
-
break;
|
|
1846
|
-
}
|
|
1847
|
-
}
|
|
1848
|
-
}
|
|
1849
|
-
if (_externalOuterPager == outer) return;
|
|
1850
|
-
[_externalOuterPager removeNestedOverlayObserver:self];
|
|
1851
|
-
_externalOuterPager = outer;
|
|
1852
|
-
_externalOuterPageActive = NO;
|
|
1853
|
-
_externalOuterTransitioning = NO;
|
|
1854
|
-
[outer addNestedOverlayObserver:self];
|
|
1855
|
-
}
|
|
1856
|
-
|
|
1857
|
-
- (BOOL)resolveExternalTopOverlay
|
|
1858
|
-
{
|
|
1859
|
-
UIView *nextView = nil;
|
|
1860
|
-
CGFloat nextHeight = 0;
|
|
1861
|
-
if (_externalTopOverlayTag > 0 && _topOverlayView == nil &&
|
|
1862
|
-
self.window != nil && !_isBeingRecycled) {
|
|
1863
|
-
for (UIView *ancestor = self.superview; ancestor != nil; ancestor = ancestor.superview) {
|
|
1864
|
-
UIView *candidate = [ancestor viewWithTag:_externalTopOverlayTag];
|
|
1865
|
-
if (candidate == nil || candidate == self ||
|
|
1866
|
-
[candidate isDescendantOfView:self] || candidate.window != self.window) continue;
|
|
1867
|
-
nextView = candidate;
|
|
1868
|
-
break;
|
|
1869
|
-
}
|
|
1870
|
-
if (nextView != nil && CGRectGetHeight(nextView.bounds) > 0) {
|
|
1871
|
-
nextHeight = MAX(0, CGRectGetMaxY([nextView convertRect:nextView.bounds
|
|
1872
|
-
toView:_containerView]));
|
|
1873
|
-
}
|
|
1874
|
-
}
|
|
1875
|
-
if (nextView == nil && _externalOuterTransitioning &&
|
|
1876
|
-
_externalTopOverlayTag > 0 && self.window != nil) {
|
|
1877
|
-
nextHeight = _externalTopOverlayHeight;
|
|
1878
|
-
}
|
|
1879
|
-
BOOL changed = _externalTopOverlayView != nextView ||
|
|
1880
|
-
fabs(_externalTopOverlayHeight - nextHeight) > 0.5;
|
|
1881
|
-
_externalTopOverlayView = nextView;
|
|
1882
|
-
_externalTopOverlayHeight = nextHeight;
|
|
1883
|
-
_topOverlayHostView.hidden = !self.hasFixedTopOverlay;
|
|
1884
|
-
_topOverlayHostView.userInteractionEnabled = _topOverlayView != nil;
|
|
1885
|
-
return changed;
|
|
1886
|
-
}
|
|
1887
|
-
|
|
1888
|
-
- (void)outerPagerDidUpdateOverlayOwner:(BOOL)active transitioning:(BOOL)transitioning
|
|
1889
|
-
{
|
|
1890
|
-
if (_isBeingRecycled || _externalOuterPager == nil || _externalTopOverlayTag <= 0) return;
|
|
1891
|
-
if (_externalOuterPageActive == active && _externalOuterTransitioning == transitioning) return;
|
|
1892
|
-
BOOL wasTransitioning = _externalOuterTransitioning;
|
|
1893
|
-
_externalOuterPageActive = active;
|
|
1894
|
-
_externalOuterTransitioning = transitioning;
|
|
1895
|
-
if (transitioning && !wasTransitioning) {
|
|
1896
|
-
[self updateTopScrollEdgeForScrollView:nil];
|
|
1897
|
-
[self liftSharedHeadersForPagerTransition:@"outer"];
|
|
1898
|
-
} else if (!transitioning && wasTransitioning &&
|
|
1899
|
-
!_transitioning && !_isPagerDragging && active) {
|
|
1900
|
-
[self attachSharedHeadersToScrollView:_observedScrollView];
|
|
1901
|
-
}
|
|
1902
|
-
[self updateTopScrollEdgeForScrollView:transitioning ? nil : _observedScrollView];
|
|
1903
|
-
[self updateScrollEdgeContentMasks];
|
|
1904
|
-
[self setNeedsLayout];
|
|
1905
|
-
}
|
|
1906
|
-
|
|
1907
|
-
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection
|
|
1908
|
-
{
|
|
1909
|
-
[super traitCollectionDidChange:previousTraitCollection];
|
|
1910
|
-
if (previousTraitCollection.userInterfaceStyle != self.traitCollection.userInterfaceStyle) {
|
|
1911
|
-
[self syncScrollEdgeAppearance];
|
|
1912
|
-
}
|
|
1913
|
-
}
|
|
1914
|
-
|
|
1915
|
-
- (void)syncScrollEdgeAppearance
|
|
1916
|
-
{
|
|
1917
|
-
BOOL active = _topScrollEdgeHard &&
|
|
1918
|
-
(self.hasFixedTopOverlay || _stickyHeaderView != nil) && self.window != nil &&
|
|
1919
|
-
!_isBeingRecycled;
|
|
1920
|
-
UIUserInterfaceStyle style = UIUserInterfaceStyleUnspecified;
|
|
1921
|
-
if (active) {
|
|
1922
|
-
if ([_topOverlayColorScheme isEqualToString:@"dark"]) {
|
|
1923
|
-
style = UIUserInterfaceStyleDark;
|
|
1924
|
-
} else if ([_topOverlayColorScheme isEqualToString:@"light"]) {
|
|
1925
|
-
style = UIUserInterfaceStyleLight;
|
|
1926
|
-
} else {
|
|
1927
|
-
style = self.traitCollection.userInterfaceStyle;
|
|
1928
|
-
}
|
|
1929
|
-
}
|
|
1930
|
-
if (_topOverlayHostView.overrideUserInterfaceStyle == style) return;
|
|
1931
|
-
_topOverlayHostView.overrideUserInterfaceStyle = style;
|
|
1932
|
-
_pinnedStickyHostView.overrideUserInterfaceStyle = style;
|
|
1933
|
-
}
|
|
1934
|
-
|
|
1935
|
-
- (void)restoreScrollEdgeContentMasks
|
|
1936
|
-
{
|
|
1937
|
-
if (_sharedHeaderHostView.maskView == _sharedHeaderMaskView) {
|
|
1938
|
-
_sharedHeaderHostView.maskView = _originalSharedHeaderMaskView;
|
|
1939
|
-
}
|
|
1940
|
-
_sharedHeaderMaskView = nil;
|
|
1941
|
-
_originalSharedHeaderMaskView = nil;
|
|
1942
|
-
for (UIView *page in _ownedPageMasks.keyEnumerator.allObjects) {
|
|
1943
|
-
if (page.maskView == [_ownedPageMasks objectForKey:page]) {
|
|
1944
|
-
id original = [_originalPageMasks objectForKey:page];
|
|
1945
|
-
page.maskView = original == NSNull.null ? nil : original;
|
|
1946
|
-
}
|
|
1947
|
-
}
|
|
1948
|
-
[_ownedPageMasks removeAllObjects];
|
|
1949
|
-
[_originalPageMasks removeAllObjects];
|
|
1950
|
-
_pageMaskBoundary = 0;
|
|
1951
|
-
}
|
|
1952
|
-
|
|
1953
|
-
- (void)updateScrollEdgeContentMasks
|
|
1954
|
-
{
|
|
1955
|
-
BOOL enabled = _topScrollEdgeHard &&
|
|
1956
|
-
(self.hasFixedTopOverlay || _stickyHeaderView != nil) &&
|
|
1957
|
-
self.window != nil && !_isBeingRecycled;
|
|
1958
|
-
if (!enabled) {
|
|
1959
|
-
[self restoreScrollEdgeContentMasks];
|
|
1960
|
-
return;
|
|
1961
|
-
}
|
|
1962
|
-
if (self.hasFixedTopOverlay && _sharedHeaderHostView.window == self.window &&
|
|
1963
|
-
CGRectGetHeight(_sharedHeaderHostView.bounds) > 0 &&
|
|
1964
|
-
CGRectGetHeight(_topOverlayHostView.bounds) > 0) {
|
|
1965
|
-
if (_sharedHeaderMaskView == nil) {
|
|
1966
|
-
_originalSharedHeaderMaskView = _sharedHeaderHostView.maskView;
|
|
1967
|
-
_sharedHeaderMaskView = [UIView new];
|
|
1968
|
-
_sharedHeaderMaskView.backgroundColor = UIColor.blackColor;
|
|
1969
|
-
_sharedHeaderHostView.maskView = _sharedHeaderMaskView;
|
|
1970
|
-
}
|
|
1971
|
-
CGFloat topBottom = CGRectGetMaxY([_topOverlayHostView
|
|
1972
|
-
convertRect:_topOverlayHostView.bounds toView:_containerView]);
|
|
1973
|
-
CGFloat localTop = [_containerView convertPoint:CGPointMake(0, topBottom)
|
|
1974
|
-
toView:_sharedHeaderHostView].y;
|
|
1975
|
-
_sharedHeaderMaskView.frame = CGRectMake(0, localTop,
|
|
1976
|
-
CGRectGetWidth(_sharedHeaderHostView.bounds),
|
|
1977
|
-
MAX(0, CGRectGetHeight(_sharedHeaderHostView.bounds) - localTop));
|
|
1978
|
-
} else if (_sharedHeaderMaskView != nil) {
|
|
1979
|
-
if (_sharedHeaderHostView.maskView == _sharedHeaderMaskView) {
|
|
1980
|
-
_sharedHeaderHostView.maskView = _originalSharedHeaderMaskView;
|
|
1981
|
-
}
|
|
1982
|
-
_sharedHeaderMaskView = nil;
|
|
1983
|
-
_originalSharedHeaderMaskView = nil;
|
|
1984
|
-
}
|
|
1985
|
-
|
|
1986
|
-
BOOL transitioning = _transitioning || _isPagerDragging || _externalOuterTransitioning ||
|
|
1987
|
-
_sharedHeadersLiftedForPagerTransition;
|
|
1988
|
-
CGFloat boundary = CGRectGetMaxY([_topOverlayHostView
|
|
1989
|
-
convertRect:_topOverlayHostView.bounds toView:_containerView]);
|
|
1990
|
-
UIView *sticky = _stickyHeaderIsPinned ? _pinnedStickyHostView : _stickyHeaderView;
|
|
1991
|
-
if (sticky != nil && !sticky.hidden && sticky.window == self.window &&
|
|
1992
|
-
CGRectGetHeight(sticky.bounds) > 0) {
|
|
1993
|
-
boundary = MAX(boundary, CGRectGetMaxY([sticky
|
|
1994
|
-
convertRect:sticky.bounds toView:_containerView]));
|
|
1995
|
-
}
|
|
1996
|
-
_pageMaskBoundary = boundary;
|
|
1997
|
-
NSMutableSet<UIView *> *visiblePages = [NSMutableSet new];
|
|
1998
|
-
if (transitioning) {
|
|
1999
|
-
for (UIViewController *controller in _pageControllers) {
|
|
2000
|
-
UIView *page = controller.view;
|
|
2001
|
-
if (page.window != self.window ||
|
|
2002
|
-
!CGRectIntersectsRect([page convertRect:page.bounds toView:_containerView],
|
|
2003
|
-
_containerView.bounds)) continue;
|
|
2004
|
-
[visiblePages addObject:page];
|
|
2005
|
-
UIView *mask = [_ownedPageMasks objectForKey:page];
|
|
2006
|
-
if (mask == nil) {
|
|
2007
|
-
[_originalPageMasks setObject:page.maskView ?: NSNull.null forKey:page];
|
|
2008
|
-
mask = [UIView new];
|
|
2009
|
-
mask.backgroundColor = UIColor.blackColor;
|
|
2010
|
-
[_ownedPageMasks setObject:mask forKey:page];
|
|
2011
|
-
page.maskView = mask;
|
|
2012
|
-
}
|
|
2013
|
-
CGFloat localTop = [_containerView convertPoint:CGPointMake(0, boundary)
|
|
2014
|
-
toView:page].y;
|
|
2015
|
-
mask.frame = CGRectMake(0, localTop, CGRectGetWidth(page.bounds),
|
|
2016
|
-
MAX(0, CGRectGetHeight(page.bounds) - localTop));
|
|
2017
|
-
}
|
|
2018
|
-
}
|
|
2019
|
-
for (UIView *page in _ownedPageMasks.keyEnumerator.allObjects) {
|
|
2020
|
-
if ([visiblePages containsObject:page]) continue;
|
|
2021
|
-
UIView *mask = [_ownedPageMasks objectForKey:page];
|
|
2022
|
-
if (page.maskView == mask) {
|
|
2023
|
-
id original = [_originalPageMasks objectForKey:page];
|
|
2024
|
-
page.maskView = original == NSNull.null ? nil : original;
|
|
2025
|
-
}
|
|
2026
|
-
[_ownedPageMasks removeObjectForKey:page];
|
|
2027
|
-
[_originalPageMasks removeObjectForKey:page];
|
|
2028
|
-
}
|
|
2029
|
-
}
|
|
2030
|
-
|
|
2031
|
-
- (void)updateEventEmitter:(const EventEmitter::Shared &)eventEmitter
|
|
2032
|
-
{
|
|
2033
|
-
[super updateEventEmitter:eventEmitter];
|
|
2034
|
-
[self emitTopScrollEdgeCapability];
|
|
2035
|
-
}
|
|
2036
|
-
|
|
2037
|
-
- (void)emitTopScrollEdgeCapability
|
|
2038
|
-
{
|
|
2039
|
-
if (self.window == nil || _isBeingRecycled) return;
|
|
2040
|
-
const auto emitter = [self eventEmitter];
|
|
2041
|
-
if (!emitter) return;
|
|
2042
|
-
BOOL available = NO;
|
|
2043
|
-
if (@available(iOS 26.0, *)) available = YES;
|
|
2044
|
-
emitter->onScrollEdgeCapability({.available = (bool)available});
|
|
2045
|
-
}
|
|
2046
|
-
|
|
2047
|
-
- (void)updateTopScrollEdgeForScrollView:(UIScrollView *)scrollView
|
|
2048
|
-
{
|
|
2049
|
-
[self syncScrollEdgeAppearance];
|
|
2050
|
-
if (@available(iOS 26.0, *)) {
|
|
2051
|
-
if (_pendingTopOverlayAppearanceCommit) scrollView = nil;
|
|
2052
|
-
BOOL externalOwnerReady = _externalTopOverlayTag <= 0 ||
|
|
2053
|
-
_externalOuterPager == nil ||
|
|
2054
|
-
(_externalOuterPageActive && !_externalOuterTransitioning);
|
|
2055
|
-
BOOL hasOverlay = _topScrollEdgeHard && self.hasFixedTopOverlay &&
|
|
2056
|
-
externalOwnerReady && self.window != nil;
|
|
2057
|
-
BOOL hasSticky = _topScrollEdgeHard && _stickyHeaderView != nil &&
|
|
2058
|
-
externalOwnerReady && self.window != nil;
|
|
2059
|
-
BOOL enabled = (hasOverlay || hasSticky) && scrollView != nil;
|
|
2060
|
-
BOOL topHostChanged = (_topEdgeInteraction != nil) != hasOverlay ||
|
|
2061
|
-
(hasOverlay && _topEdgeInteractionHost != _topOverlayHostView);
|
|
2062
|
-
if (_topEdgeScrollView != nil && (!enabled || _topEdgeScrollView != scrollView ||
|
|
2063
|
-
topHostChanged)) {
|
|
2064
|
-
[_topEdgeInteractionHost removeInteraction:_topEdgeInteraction];
|
|
2065
|
-
_topEdgeInteraction.scrollView = nil;
|
|
2066
|
-
[_stickyEdgeInteractionHost removeInteraction:_stickyEdgeInteraction];
|
|
2067
|
-
_stickyEdgeInteraction.scrollView = nil;
|
|
2068
|
-
[_topEdgeMarker removeFromSuperview];
|
|
2069
|
-
[_stickyEdgeMarker removeFromSuperview];
|
|
2070
|
-
_topEdgeScrollView.topEdgeEffect.style = _originalTopEdgeStyle;
|
|
2071
|
-
_topEdgeInteraction = nil;
|
|
2072
|
-
_stickyEdgeInteraction = nil;
|
|
2073
|
-
_topEdgeMarker = nil;
|
|
2074
|
-
_stickyEdgeMarker = nil;
|
|
2075
|
-
_topEdgeInteractionHost = nil;
|
|
2076
|
-
_stickyEdgeInteractionHost = nil;
|
|
2077
|
-
_topEdgeScrollView = nil;
|
|
2078
|
-
_originalTopEdgeStyle = nil;
|
|
2079
|
-
}
|
|
2080
|
-
if (enabled && _topEdgeScrollView == nil) {
|
|
2081
|
-
_originalTopEdgeStyle = scrollView.topEdgeEffect.style;
|
|
2082
|
-
_topEdgeScrollView = scrollView;
|
|
2083
|
-
scrollView.topEdgeEffect.style = UIScrollEdgeEffectStyle.hardStyle;
|
|
2084
|
-
}
|
|
2085
|
-
if (hasOverlay && enabled && _topEdgeInteraction == nil) {
|
|
2086
|
-
// UIKit needs a native element to shape the edge effect around React-drawn content.
|
|
2087
|
-
_topEdgeMarker = [UILabel new];
|
|
2088
|
-
_topEdgeMarker.frame = _topOverlayHostView.bounds;
|
|
2089
|
-
_topEdgeMarker.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
|
2090
|
-
_topEdgeMarker.text = @" ";
|
|
2091
|
-
_topEdgeMarker.textColor = UIColor.clearColor;
|
|
2092
|
-
_topEdgeMarker.backgroundColor = UIColor.clearColor;
|
|
2093
|
-
_topEdgeMarker.userInteractionEnabled = NO;
|
|
2094
|
-
_topEdgeMarker.isAccessibilityElement = NO;
|
|
2095
|
-
_topEdgeMarker.accessibilityElementsHidden = YES;
|
|
2096
|
-
[_topOverlayHostView addSubview:_topEdgeMarker];
|
|
2097
|
-
_topEdgeInteraction = [UIScrollEdgeElementContainerInteraction new];
|
|
2098
|
-
_topEdgeInteraction.edge = UIRectEdgeTop;
|
|
2099
|
-
_topEdgeInteraction.scrollView = scrollView;
|
|
2100
|
-
[_topOverlayHostView addInteraction:_topEdgeInteraction];
|
|
2101
|
-
_topEdgeInteractionHost = _topOverlayHostView;
|
|
2102
|
-
}
|
|
2103
|
-
BOOL legacyStickyPinned = !_nativeSmoothHeaderScrollEnabled &&
|
|
2104
|
-
_stickyHeaderView != nil && _headerOffset >= _headerHeight - 0.5;
|
|
2105
|
-
BOOL stickyEnabled = enabled && (_stickyHeaderIsPinned || legacyStickyPinned);
|
|
2106
|
-
UIView *stickyInteractionHost = _stickyHeaderIsPinned
|
|
2107
|
-
? _pinnedStickyHostView : _stickyHeaderView;
|
|
2108
|
-
if (_stickyEdgeInteractionHost != nil &&
|
|
2109
|
-
(!stickyEnabled || _stickyEdgeInteractionHost != stickyInteractionHost)) {
|
|
2110
|
-
[_stickyEdgeInteractionHost removeInteraction:_stickyEdgeInteraction];
|
|
2111
|
-
_stickyEdgeInteraction.scrollView = nil;
|
|
2112
|
-
[_stickyEdgeMarker removeFromSuperview];
|
|
2113
|
-
_stickyEdgeMarker = nil;
|
|
2114
|
-
_stickyEdgeInteraction = nil;
|
|
2115
|
-
_stickyEdgeInteractionHost = nil;
|
|
2116
|
-
}
|
|
2117
|
-
if (stickyEnabled && _stickyEdgeInteraction == nil) {
|
|
2118
|
-
_stickyEdgeMarker = [UILabel new];
|
|
2119
|
-
_stickyEdgeMarker.frame = stickyInteractionHost.bounds;
|
|
2120
|
-
_stickyEdgeMarker.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
|
2121
|
-
_stickyEdgeMarker.text = @" ";
|
|
2122
|
-
_stickyEdgeMarker.textColor = UIColor.clearColor;
|
|
2123
|
-
_stickyEdgeMarker.backgroundColor = UIColor.clearColor;
|
|
2124
|
-
_stickyEdgeMarker.userInteractionEnabled = NO;
|
|
2125
|
-
_stickyEdgeMarker.isAccessibilityElement = NO;
|
|
2126
|
-
_stickyEdgeMarker.accessibilityElementsHidden = YES;
|
|
2127
|
-
[stickyInteractionHost addSubview:_stickyEdgeMarker];
|
|
2128
|
-
_stickyEdgeInteraction = [UIScrollEdgeElementContainerInteraction new];
|
|
2129
|
-
_stickyEdgeInteraction.edge = UIRectEdgeTop;
|
|
2130
|
-
_stickyEdgeInteraction.scrollView = scrollView;
|
|
2131
|
-
[stickyInteractionHost addInteraction:_stickyEdgeInteraction];
|
|
2132
|
-
_stickyEdgeInteractionHost = stickyInteractionHost;
|
|
2133
|
-
}
|
|
2134
|
-
[self updateScrollEdgeContentMasks];
|
|
2135
|
-
}
|
|
2136
|
-
}
|
|
2137
|
-
|
|
2138
1715
|
- (void)dealloc
|
|
2139
1716
|
{
|
|
2140
|
-
[self updateTopScrollEdgeForScrollView:nil];
|
|
2141
1717
|
[self cancelHeaderSettledCheck];
|
|
2142
1718
|
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"OneKeyNativeListScrollCommandAccepted" object:nil];
|
|
2143
1719
|
for (UIScrollView *scrollView in _originalInsets.keyEnumerator) {
|
|
@@ -2190,7 +1766,6 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
2190
1766
|
_hasPendingDirectNativePagerChange = NO;
|
|
2191
1767
|
if (_directNativePagerEnabled == enabled) return;
|
|
2192
1768
|
|
|
2193
|
-
[self restoreScrollEdgeContentMasks];
|
|
2194
1769
|
[self detachScrollObserver];
|
|
2195
1770
|
[self restoreSharedHeadersToContainer];
|
|
2196
1771
|
if (_blockerGesture != nil) {
|
|
@@ -2266,33 +1841,8 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
2266
1841
|
|
|
2267
1842
|
#pragma mark - Smooth shared header ownership
|
|
2268
1843
|
|
|
2269
|
-
- (void)restorePinnedStickyHeader
|
|
2270
|
-
{
|
|
2271
|
-
if (!_stickyHeaderIsPinned) return;
|
|
2272
|
-
_stickyHeaderIsPinned = NO;
|
|
2273
|
-
_stickyHeaderView.transform = CGAffineTransformIdentity;
|
|
2274
|
-
_nativeTabBarView.transform = CGAffineTransformIdentity;
|
|
2275
|
-
_nativeSubHeaderView.transform = CGAffineTransformIdentity;
|
|
2276
|
-
[_stickyHeaderView removeFromSuperview];
|
|
2277
|
-
[_nativeTabBarView removeFromSuperview];
|
|
2278
|
-
[_nativeSubHeaderView removeFromSuperview];
|
|
2279
|
-
if (_stickyHeaderView != nil) [_sharedHeaderHostView addSubview:_stickyHeaderView];
|
|
2280
|
-
[_sharedHeaderHostView addSubview:_nativeTabBarView];
|
|
2281
|
-
[_sharedHeaderHostView addSubview:_nativeSubHeaderView];
|
|
2282
|
-
_pinnedStickyHostView.hidden = YES;
|
|
2283
|
-
_pinnedStickyHostView.layer.zPosition = 0;
|
|
2284
|
-
[_containerView addSubview:_pinnedStickyHostView];
|
|
2285
|
-
if ([_pagerScrollView isKindOfClass:RNCCollapsiblePagerDirectScrollView.class]) {
|
|
2286
|
-
((RNCCollapsiblePagerDirectScrollView *)_pagerScrollView).excludedHeaderView = _sharedHeaderHostView;
|
|
2287
|
-
}
|
|
2288
|
-
[_nativeTabBarView updateAncestorGesturePrecedence];
|
|
2289
|
-
[_nativeSubHeaderView updateAncestorGesturePrecedence];
|
|
2290
|
-
}
|
|
2291
|
-
|
|
2292
1844
|
- (void)restoreSharedHeadersToContainer
|
|
2293
1845
|
{
|
|
2294
|
-
[self restorePinnedStickyHeader];
|
|
2295
|
-
[self updateTopScrollEdgeForScrollView:_observedScrollView];
|
|
2296
1846
|
_sharedHeaderScrollView = nil;
|
|
2297
1847
|
_sharedHeadersLiftedForPagerTransition = NO;
|
|
2298
1848
|
_sharedHeaderHostView.layer.zPosition = 0;
|
|
@@ -2300,15 +1850,11 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
2300
1850
|
[_containerView addSubview:_sharedHeaderHostView];
|
|
2301
1851
|
}
|
|
2302
1852
|
[self layoutSharedHeaders];
|
|
2303
|
-
if (self.hasFixedTopOverlay) {
|
|
2304
|
-
[_containerView bringSubviewToFront:_topOverlayHostView];
|
|
2305
|
-
}
|
|
2306
1853
|
}
|
|
2307
1854
|
|
|
2308
1855
|
- (void)attachSharedHeadersToScrollView:(UIScrollView *)scrollView
|
|
2309
1856
|
{
|
|
2310
1857
|
if (!_nativeSmoothHeaderScrollEnabled || _transitioning || _isPagerDragging ||
|
|
2311
|
-
_externalOuterTransitioning ||
|
|
2312
1858
|
scrollView == nil || _isBeingRecycled) return;
|
|
2313
1859
|
if ((UIView *)scrollView == _sharedHeaderHostView ||
|
|
2314
1860
|
[scrollView isDescendantOfView:_sharedHeaderHostView]) {
|
|
@@ -2320,16 +1866,13 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
2320
1866
|
}
|
|
2321
1867
|
if (_sharedHeaderScrollView == scrollView &&
|
|
2322
1868
|
_sharedHeaderHostView.superview == scrollView) {
|
|
2323
|
-
_sharedHeaderHostView.layer.zPosition =
|
|
2324
|
-
_topScrollEdgeHard && (self.hasFixedTopOverlay || _stickyHeaderView != nil) ? 0 : 1000;
|
|
2325
1869
|
[self layoutSharedHeaders];
|
|
2326
1870
|
return;
|
|
2327
1871
|
}
|
|
2328
1872
|
|
|
2329
1873
|
_sharedHeaderScrollView = scrollView;
|
|
2330
1874
|
_sharedHeadersLiftedForPagerTransition = NO;
|
|
2331
|
-
_sharedHeaderHostView.layer.zPosition =
|
|
2332
|
-
_topScrollEdgeHard && (self.hasFixedTopOverlay || _stickyHeaderView != nil) ? 0 : 1000;
|
|
1875
|
+
_sharedHeaderHostView.layer.zPosition = 1000;
|
|
2333
1876
|
if (_sharedHeaderHostView.superview != scrollView) {
|
|
2334
1877
|
[scrollView addSubview:_sharedHeaderHostView];
|
|
2335
1878
|
}
|
|
@@ -2376,114 +1919,56 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
2376
1919
|
|
|
2377
1920
|
_sharedHeaderHostView.frame = CGRectMake(
|
|
2378
1921
|
0,
|
|
2379
|
-
attachedToList ? -totalHeight :
|
|
1922
|
+
attachedToList ? -totalHeight : 0,
|
|
2380
1923
|
width,
|
|
2381
1924
|
totalHeight
|
|
2382
1925
|
);
|
|
2383
1926
|
CGFloat stickyY = _headerHeight;
|
|
2384
1927
|
_headerView.frame = CGRectMake(0, 0, width, _headerHeight);
|
|
2385
|
-
|
|
2386
|
-
? [_sharedHeaderScrollView convertPoint:CGPointMake(0, self.effectiveTopOverlayHeight) fromView:_containerView]
|
|
2387
|
-
: CGPointMake(0, self.effectiveTopOverlayHeight);
|
|
2388
|
-
_pinnedStickyHostView.frame = CGRectMake(
|
|
2389
|
-
pinnedOrigin.x, pinnedOrigin.y, width, _stickyHeaderHeight);
|
|
2390
|
-
CGFloat stickyChildY = _stickyHeaderIsPinned ? 0 : stickyY;
|
|
2391
|
-
_stickyHeaderView.frame = CGRectMake(0, stickyChildY, width, _stickyHeaderHeight);
|
|
1928
|
+
_stickyHeaderView.frame = CGRectMake(0, stickyY, width, _stickyHeaderHeight);
|
|
2392
1929
|
CGFloat nativeTabBarVisibleHeight = _nativeTabBarView.hidden
|
|
2393
1930
|
? 0
|
|
2394
1931
|
: MIN(_stickyHeaderHeight, _nativeTabBarHeight);
|
|
2395
1932
|
_nativeTabBarView.frame = CGRectMake(
|
|
2396
1933
|
0,
|
|
2397
|
-
|
|
1934
|
+
stickyY,
|
|
2398
1935
|
width,
|
|
2399
1936
|
nativeTabBarVisibleHeight
|
|
2400
1937
|
);
|
|
2401
1938
|
_nativeSubHeaderView.frame = CGRectMake(
|
|
2402
1939
|
0,
|
|
2403
|
-
|
|
1940
|
+
stickyY + nativeTabBarVisibleHeight,
|
|
2404
1941
|
width,
|
|
2405
1942
|
MIN(
|
|
2406
1943
|
MAX(0, _stickyHeaderHeight - nativeTabBarVisibleHeight),
|
|
2407
1944
|
_nativeSubHeaderHeight
|
|
2408
1945
|
)
|
|
2409
1946
|
);
|
|
2410
|
-
_topOverlayHostView.frame = CGRectMake(0, 0, width, self.effectiveTopOverlayHeight);
|
|
2411
|
-
_topOverlayView.frame = _topOverlayHostView.bounds;
|
|
2412
1947
|
[self applyHeaderOffset];
|
|
2413
1948
|
}
|
|
2414
1949
|
|
|
2415
|
-
- (void)
|
|
1950
|
+
- (void)offsetDiag:(NSString *)reason page:(NSInteger)index scroll:(UIScrollView *)scroll
|
|
2416
1951
|
{
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
if (!
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
if (_stickyHeaderIsPinned && shouldPin && _pinnedStickyHostView.superview != scrollView) {
|
|
2433
|
-
[self updateTopScrollEdgeForScrollView:nil];
|
|
2434
|
-
[scrollView addSubview:_pinnedStickyHostView];
|
|
2435
|
-
[self updateTopScrollEdgeForScrollView:_observedScrollView];
|
|
2436
|
-
}
|
|
2437
|
-
if (_stickyHeaderIsPinned == shouldPin) {
|
|
2438
|
-
if (shouldPin) {
|
|
2439
|
-
CGPoint origin = [scrollView convertPoint:CGPointMake(0, self.effectiveTopOverlayHeight)
|
|
2440
|
-
fromView:_containerView];
|
|
2441
|
-
_pinnedStickyHostView.frame = CGRectMake(origin.x, origin.y,
|
|
2442
|
-
CGRectGetWidth(self.bounds), _stickyHeaderHeight);
|
|
2443
|
-
}
|
|
2444
|
-
return;
|
|
2445
|
-
}
|
|
2446
|
-
|
|
2447
|
-
_stickyHeaderIsPinned = shouldPin;
|
|
2448
|
-
UIView *host = shouldPin ? _pinnedStickyHostView : _sharedHeaderHostView;
|
|
2449
|
-
_stickyHeaderView.transform = CGAffineTransformIdentity;
|
|
2450
|
-
_nativeTabBarView.transform = CGAffineTransformIdentity;
|
|
2451
|
-
_nativeSubHeaderView.transform = CGAffineTransformIdentity;
|
|
2452
|
-
[_stickyHeaderView removeFromSuperview];
|
|
2453
|
-
[_nativeTabBarView removeFromSuperview];
|
|
2454
|
-
[_nativeSubHeaderView removeFromSuperview];
|
|
2455
|
-
if (_stickyHeaderView != nil) [host addSubview:_stickyHeaderView];
|
|
2456
|
-
[host addSubview:_nativeTabBarView];
|
|
2457
|
-
[host addSubview:_nativeSubHeaderView];
|
|
2458
|
-
CGFloat childY = shouldPin ? 0 : _headerHeight;
|
|
2459
|
-
CGFloat width = CGRectGetWidth(self.bounds);
|
|
2460
|
-
CGFloat tabHeight = _nativeTabBarView.hidden ? 0 : MIN(_stickyHeaderHeight, _nativeTabBarHeight);
|
|
2461
|
-
_stickyHeaderView.frame = CGRectMake(0, childY, width, _stickyHeaderHeight);
|
|
2462
|
-
_nativeTabBarView.frame = CGRectMake(0, childY, width, tabHeight);
|
|
2463
|
-
_nativeSubHeaderView.frame = CGRectMake(0, childY + tabHeight, width,
|
|
2464
|
-
MIN(MAX(0, _stickyHeaderHeight - tabHeight), _nativeSubHeaderHeight));
|
|
2465
|
-
_pinnedStickyHostView.hidden = !shouldPin;
|
|
2466
|
-
if ([_pagerScrollView isKindOfClass:RNCCollapsiblePagerDirectScrollView.class]) {
|
|
2467
|
-
((RNCCollapsiblePagerDirectScrollView *)_pagerScrollView).excludedHeaderView =
|
|
2468
|
-
shouldPin ? _pinnedStickyHostView : _sharedHeaderHostView;
|
|
2469
|
-
}
|
|
2470
|
-
if (shouldPin) {
|
|
2471
|
-
[scrollView addSubview:_pinnedStickyHostView];
|
|
2472
|
-
_pinnedStickyHostView.layer.zPosition = 1000;
|
|
2473
|
-
CGPoint origin = [scrollView convertPoint:CGPointMake(0, self.effectiveTopOverlayHeight)
|
|
2474
|
-
fromView:_containerView];
|
|
2475
|
-
_pinnedStickyHostView.frame = CGRectMake(origin.x, origin.y, width, _stickyHeaderHeight);
|
|
2476
|
-
} else {
|
|
2477
|
-
_pinnedStickyHostView.layer.zPosition = 0;
|
|
2478
|
-
[_containerView addSubview:_pinnedStickyHostView];
|
|
2479
|
-
}
|
|
2480
|
-
[_nativeTabBarView updateAncestorGesturePrecedence];
|
|
2481
|
-
[_nativeSubHeaderView updateAncestorGesturePrecedence];
|
|
2482
|
-
[self updateTopScrollEdgeForScrollView:_observedScrollView];
|
|
1952
|
+
#if DEBUG
|
|
1953
|
+
NSString *key = index >= 0 && index < _pageControllers.count ? [self pageKeyForIndex:index] : @"none";
|
|
1954
|
+
if (![@[@"portfolio", @"perps", @"defi", @"nft", @"history"] containsObject:key]) key = @"other";
|
|
1955
|
+
NSNumber *saved = index >= 0 && index < _pageControllers.count ? _pageOffsets[[self pageKeyForIndex:index]] : nil;
|
|
1956
|
+
UIView *component = scroll == nil ? nil : RNCScrollComponentView(scroll);
|
|
1957
|
+
RNCCollapsiblePagerLog([NSString stringWithFormat:
|
|
1958
|
+
@"[HOME-OFFSET-DIAG] pager phase=%@ seq=%lu wallMs=%.0f mono=%.6f host=%p generation=%lu transitionId=%lu page=%ld key=%@ current=%ld destination=%ld transition=%d dragging=%d scroll=%p tag=%ld component=%p componentTag=%ld observed=%p ownerIndex=%ld ownerGeneration=%lu synthetic=%d cacheExists=%d cache=%.4f header=%.4f headerHeight=%ld physicalY=%.4f insetTop=%.4f insetBottom=%.4f logicalY=%.4f contentHeight=%.4f boundsHeight=%.4f",
|
|
1959
|
+
reason, (unsigned long)++_offsetDiagSequence, NSDate.date.timeIntervalSince1970 * 1000, CACurrentMediaTime(),
|
|
1960
|
+
(__bridge void *)self, (unsigned long)_generation, (unsigned long)_transitionId, (long)index, key,
|
|
1961
|
+
(long)_currentIndex, (long)_destinationIndex, _transitioning, _isPagerDragging,
|
|
1962
|
+
(__bridge void *)scroll, (long)scroll.tag, (__bridge void *)component, (long)component.tag,
|
|
1963
|
+
(__bridge void *)_observedScrollView, (long)_observedPageIndex, (unsigned long)_observedPageGeneration, _syntheticPageRestore, saved != nil, saved.doubleValue, _headerOffset, (long)_headerHeight,
|
|
1964
|
+
scroll.contentOffset.y, scroll.contentInset.top, scroll.contentInset.bottom,
|
|
1965
|
+
scroll.contentOffset.y + scroll.contentInset.top, scroll.contentSize.height, scroll.bounds.size.height]);
|
|
1966
|
+
#endif
|
|
2483
1967
|
}
|
|
2484
1968
|
|
|
2485
1969
|
- (void)preparePageForHorizontalTransitionAtIndex:(NSInteger)pageIndex
|
|
2486
1970
|
{
|
|
1971
|
+
[self offsetDiag:@"prepare-check" page:pageIndex scroll:nil];
|
|
2487
1972
|
if (!_nativeSmoothHeaderScrollEnabled ||
|
|
2488
1973
|
pageIndex < 0 || pageIndex >= _pageControllers.count) return;
|
|
2489
1974
|
UIScrollView *scrollView = [self verticalScrollViewForPageAtIndex:pageIndex];
|
|
@@ -2502,6 +1987,11 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
2502
1987
|
_transitionHeaderOffset = _headerOffset;
|
|
2503
1988
|
_transitionPageOffsets = [_pageOffsets copy];
|
|
2504
1989
|
_transitionCompensatedPages = [NSMutableIndexSet new];
|
|
1990
|
+
#if DEBUG
|
|
1991
|
+
_transitionDiagBucket = -1;
|
|
1992
|
+
[self offsetDiag:[NSString stringWithFormat:@"screen-begin-source=%ld-savedQ=%.4f", (long)_transitionSourceIndex,
|
|
1993
|
+
[_transitionPageOffsets[self.currentPageKey] doubleValue]] page:_currentIndex scroll:nil];
|
|
1994
|
+
#endif
|
|
2505
1995
|
}
|
|
2506
1996
|
|
|
2507
1997
|
- (void)updatePageStateTransitionProgress:(CGFloat)progress
|
|
@@ -2518,6 +2008,16 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
2518
2008
|
CGFloat firstQ = [_transitionPageOffsets[[self pageKeyForIndex:first]] doubleValue];
|
|
2519
2009
|
CGFloat secondQ = [_transitionPageOffsets[[self pageKeyForIndex:second]] doubleValue];
|
|
2520
2010
|
_headerOffset = _transitionHeaderOffset;
|
|
2011
|
+
#if DEBUG
|
|
2012
|
+
NSInteger bucket = (NSInteger)floor(fraction * 4);
|
|
2013
|
+
if (_transitionDiagBucket != bucket) {
|
|
2014
|
+
_transitionDiagBucket = bucket;
|
|
2015
|
+
[self offsetDiag:[NSString stringWithFormat:
|
|
2016
|
+
@"screen-progress-kind=%@-source=%ld-target=%ld-sourceQ=%.4f-targetQ=%.4f-position=%.4f-fraction=%.4f",
|
|
2017
|
+
_isPagerDragging ? @"interactive" : @"programmatic-endpoint", (long)first, (long)second,
|
|
2018
|
+
firstQ, secondQ, progress, fraction] page:_currentIndex scroll:nil];
|
|
2019
|
+
}
|
|
2020
|
+
#endif
|
|
2521
2021
|
_syntheticPageRestore = YES;
|
|
2522
2022
|
NSInteger visibleFirst = MAX(0, MIN((NSInteger)floor(progress), (NSInteger)_pageControllers.count - 1));
|
|
2523
2023
|
NSInteger visibleLast = MIN(visibleFirst + 1, (NSInteger)_pageControllers.count - 1);
|
|
@@ -2559,6 +2059,10 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
2559
2059
|
_transitionPageOffsets = nil;
|
|
2560
2060
|
_transitionCompensatedPages = nil;
|
|
2561
2061
|
[self layoutSharedHeaders];
|
|
2062
|
+
#if DEBUG
|
|
2063
|
+
[self offsetDiag:[NSString stringWithFormat:@"screen-finish-source=%ld-cancelled=%d", (long)_transitionSourceIndex,
|
|
2064
|
+
_currentIndex == _transitionSourceIndex] page:_currentIndex scroll:nil];
|
|
2065
|
+
#endif
|
|
2562
2066
|
}
|
|
2563
2067
|
|
|
2564
2068
|
#pragma mark - React mounting
|
|
@@ -2615,7 +2119,9 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
2615
2119
|
if (!_nativeSmoothHeaderScrollEnabled && _transitionPageOffsets == nil && !_syntheticPageRestore &&
|
|
2616
2120
|
![_pendingPageRestoreKeys containsObject:pageKey] &&
|
|
2617
2121
|
(ownsObservedPage || _pageOffsets[pageKey] == nil)) {
|
|
2122
|
+
[self offsetDiag:@"mount-release-save-before" page:index scroll:scrollView];
|
|
2618
2123
|
_pageOffsets[pageKey] = @(scrollView.contentOffset.y + scrollView.contentInset.top);
|
|
2124
|
+
[self offsetDiag:@"mount-release-save-after" page:index scroll:scrollView];
|
|
2619
2125
|
}
|
|
2620
2126
|
break;
|
|
2621
2127
|
}
|
|
@@ -2631,27 +2137,6 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
2631
2137
|
- (void)mountingTransactionDidMount:(const MountingTransaction &)transaction
|
|
2632
2138
|
withSurfaceTelemetry:(const SurfaceTelemetry &)surfaceTelemetry
|
|
2633
2139
|
{
|
|
2634
|
-
if (_needsSlotRebuild && !_deferTopEdgeSlotRebuild &&
|
|
2635
|
-
!_transitioning && !_isPagerDragging) {
|
|
2636
|
-
[self rebuildSlots];
|
|
2637
|
-
}
|
|
2638
|
-
[self registerExternalOuterPager];
|
|
2639
|
-
if ([self resolveExternalTopOverlay]) {
|
|
2640
|
-
[self reapplyInsetsToObservedScrollView];
|
|
2641
|
-
[self setNeedsLayout];
|
|
2642
|
-
}
|
|
2643
|
-
if (_pendingTopOverlayAppearanceCommit) {
|
|
2644
|
-
_pendingTopOverlayAppearanceCommit = NO;
|
|
2645
|
-
BOOL localOverlayReady = _topOverlayView.superview == _topOverlayHostView &&
|
|
2646
|
-
_topOverlayView.window == self.window;
|
|
2647
|
-
BOOL externalOverlayReady = _externalTopOverlayTag > 0 &&
|
|
2648
|
-
_externalTopOverlayView.window == self.window;
|
|
2649
|
-
if (!_isBeingRecycled && _topScrollEdgeHard && self.window != nil &&
|
|
2650
|
-
(localOverlayReady || externalOverlayReady)) {
|
|
2651
|
-
[self updateTopScrollEdgeForScrollView:_observedScrollView];
|
|
2652
|
-
}
|
|
2653
|
-
}
|
|
2654
|
-
[self updateScrollEdgeContentMasks];
|
|
2655
2140
|
[_mountingRemovedScrollViews removeAllObjects];
|
|
2656
2141
|
if (!_nativeSmoothHeaderScrollEnabled || _isBeingRecycled || self.window == nil ||
|
|
2657
2142
|
_currentIndex < 0 || _currentIndex >= _pageControllers.count) return;
|
|
@@ -2729,11 +2214,7 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
2729
2214
|
if (_isBeingRecycled) return;
|
|
2730
2215
|
NSInteger safeIndex = MIN(MAX(index, 0), _logicalChildren.count);
|
|
2731
2216
|
[_logicalChildren insertObject:childComponentView atIndex:safeIndex];
|
|
2732
|
-
|
|
2733
|
-
_needsSlotRebuild = YES;
|
|
2734
|
-
} else {
|
|
2735
|
-
[self rebuildSlots];
|
|
2736
|
-
}
|
|
2217
|
+
[self rebuildSlots];
|
|
2737
2218
|
}
|
|
2738
2219
|
|
|
2739
2220
|
- (void)unmountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView
|
|
@@ -2744,32 +2225,16 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
2744
2225
|
if (existingIndex == NSNotFound) return;
|
|
2745
2226
|
[childComponentView removeFromSuperview];
|
|
2746
2227
|
[_logicalChildren removeObjectAtIndex:existingIndex];
|
|
2747
|
-
|
|
2748
|
-
_needsSlotRebuild = YES;
|
|
2749
|
-
} else {
|
|
2750
|
-
[self rebuildSlots];
|
|
2751
|
-
}
|
|
2228
|
+
[self rebuildSlots];
|
|
2752
2229
|
}
|
|
2753
2230
|
|
|
2754
2231
|
- (void)rebuildSlots
|
|
2755
2232
|
{
|
|
2756
|
-
if (_deferTopEdgeSlotRebuild) {
|
|
2757
|
-
_needsSlotRebuild = YES;
|
|
2758
|
-
return;
|
|
2759
|
-
}
|
|
2760
2233
|
if (_transitioning || _isPagerDragging) {
|
|
2761
2234
|
_needsSlotRebuild = YES;
|
|
2762
2235
|
return;
|
|
2763
2236
|
}
|
|
2764
|
-
if (_topScrollEdgeHard &&
|
|
2765
|
-
_logicalChildren.count != _pageKeys.count + 2 &&
|
|
2766
|
-
_logicalChildren.count != _pageKeys.count + 3) {
|
|
2767
|
-
_needsSlotRebuild = YES;
|
|
2768
|
-
return;
|
|
2769
|
-
}
|
|
2770
2237
|
_needsSlotRebuild = NO;
|
|
2771
|
-
_deferTopEdgeSlotRebuild = NO;
|
|
2772
|
-
[self restoreScrollEdgeContentMasks];
|
|
2773
2238
|
[self detachScrollObserver];
|
|
2774
2239
|
[self restoreSharedHeadersToContainer];
|
|
2775
2240
|
// OneKey patch: Fabric reuses these views without resetting transforms
|
|
@@ -2781,15 +2246,11 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
2781
2246
|
_nativeSubHeaderView.transform = CGAffineTransformIdentity;
|
|
2782
2247
|
[_headerView removeFromSuperview];
|
|
2783
2248
|
[_stickyHeaderView removeFromSuperview];
|
|
2784
|
-
[self updateTopScrollEdgeForScrollView:nil];
|
|
2785
|
-
[_topOverlayView removeFromSuperview];
|
|
2786
2249
|
for (UIViewController *controller in _pageControllers) {
|
|
2787
2250
|
[controller.view removeFromSuperview];
|
|
2788
2251
|
}
|
|
2789
2252
|
_headerView = nil;
|
|
2790
2253
|
_stickyHeaderView = nil;
|
|
2791
|
-
_topOverlayView = nil;
|
|
2792
|
-
[self updateTopScrollEdgeForScrollView:nil];
|
|
2793
2254
|
[_pageControllers removeAllObjects];
|
|
2794
2255
|
|
|
2795
2256
|
if (_logicalChildren.count > 0) {
|
|
@@ -2800,15 +2261,7 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
2800
2261
|
_stickyHeaderView = _logicalChildren[1];
|
|
2801
2262
|
[_sharedHeaderHostView addSubview:_stickyHeaderView];
|
|
2802
2263
|
}
|
|
2803
|
-
|
|
2804
|
-
_logicalChildren.count == _pageKeys.count + 3;
|
|
2805
|
-
NSInteger pageSlotStart = hasOverlaySlot ? 3 : 2;
|
|
2806
|
-
if (hasOverlaySlot) {
|
|
2807
|
-
_topOverlayView = _logicalChildren[2];
|
|
2808
|
-
[_topOverlayHostView addSubview:_topOverlayView];
|
|
2809
|
-
}
|
|
2810
|
-
[self resolveExternalTopOverlay];
|
|
2811
|
-
for (NSInteger index = pageSlotStart; index < _logicalChildren.count; index++) {
|
|
2264
|
+
for (NSInteger index = 2; index < _logicalChildren.count; index++) {
|
|
2812
2265
|
UIView *page = _logicalChildren[index];
|
|
2813
2266
|
UIViewController *controller = [UIViewController new];
|
|
2814
2267
|
[controller.view addSubview:page];
|
|
@@ -2847,10 +2300,6 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
2847
2300
|
if (!_nativeTabBarView.hidden) [_sharedHeaderHostView bringSubviewToFront:_nativeTabBarView];
|
|
2848
2301
|
if (!_nativeSubHeaderView.hidden) [_sharedHeaderHostView bringSubviewToFront:_nativeSubHeaderView];
|
|
2849
2302
|
[_containerView bringSubviewToFront:_sharedHeaderHostView];
|
|
2850
|
-
if (_stickyHeaderIsPinned) {
|
|
2851
|
-
[_pinnedStickyHostView.superview bringSubviewToFront:_pinnedStickyHostView];
|
|
2852
|
-
}
|
|
2853
|
-
if (self.hasFixedTopOverlay) [_containerView bringSubviewToFront:_topOverlayHostView];
|
|
2854
2303
|
[self setNeedsLayout];
|
|
2855
2304
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
2856
2305
|
if (!self->_isBeingRecycled) {
|
|
@@ -2863,10 +2312,7 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
2863
2312
|
- (void)layoutSubviews
|
|
2864
2313
|
{
|
|
2865
2314
|
[super layoutSubviews];
|
|
2866
|
-
[self syncScrollEdgeAppearance];
|
|
2867
2315
|
_containerView.frame = self.bounds;
|
|
2868
|
-
[self registerExternalOuterPager];
|
|
2869
|
-
BOOL externalHeightChanged = [self resolveExternalTopOverlay];
|
|
2870
2316
|
if (_directNativePagerEnabled) {
|
|
2871
2317
|
_pagerScrollView.frame = _containerView.bounds;
|
|
2872
2318
|
} else {
|
|
@@ -2929,9 +2375,6 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
2929
2375
|
}
|
|
2930
2376
|
}
|
|
2931
2377
|
[self layoutSharedHeaders];
|
|
2932
|
-
if (externalHeightChanged) [self reapplyInsetsToObservedScrollView];
|
|
2933
|
-
[self updateTopScrollEdgeForScrollView:_observedScrollView];
|
|
2934
|
-
[self updateScrollEdgeContentMasks];
|
|
2935
2378
|
[self updateHeaderSettledStateForceBusy:NO];
|
|
2936
2379
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
2937
2380
|
if (!self->_isBeingRecycled) {
|
|
@@ -2943,16 +2386,9 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
2943
2386
|
|
|
2944
2387
|
- (void)prepareForRecycle
|
|
2945
2388
|
{
|
|
2946
|
-
[_externalOuterPager removeNestedOverlayObserver:self];
|
|
2947
|
-
_externalOuterPager = nil;
|
|
2948
|
-
[self cancelTopInsetReboundCheck];
|
|
2949
|
-
[self restoreScrollEdgeContentMasks];
|
|
2950
|
-
[self updateTopScrollEdgeForScrollView:nil];
|
|
2951
2389
|
[self cancelHeaderSettledCheck];
|
|
2952
2390
|
[self publishHeaderSettledAtTop:NO identityChanged:NO];
|
|
2953
2391
|
_isBeingRecycled = YES;
|
|
2954
|
-
_pendingTopOverlayAppearanceCommit = NO;
|
|
2955
|
-
[self syncScrollEdgeAppearance];
|
|
2956
2392
|
_generation++;
|
|
2957
2393
|
[_mountingRemovedScrollViews removeAllObjects];
|
|
2958
2394
|
_needsScrollObserverReattachAfterMount = NO;
|
|
@@ -2972,7 +2408,9 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
2972
2408
|
if (appliedTop != nil && scrollView.refreshControl != nil) {
|
|
2973
2409
|
original.top += MAX(0, scrollView.contentInset.top - appliedTop.doubleValue);
|
|
2974
2410
|
}
|
|
2411
|
+
[self offsetDiag:@"release-original-inset-before" page:_currentIndex scroll:scrollView];
|
|
2975
2412
|
scrollView.contentInset = original;
|
|
2413
|
+
[self offsetDiag:@"release-original-inset-after" page:_currentIndex scroll:scrollView];
|
|
2976
2414
|
}
|
|
2977
2415
|
NSValue *indicatorValue = [_originalIndicatorInsets objectForKey:scrollView];
|
|
2978
2416
|
if (indicatorValue != nil) {
|
|
@@ -3001,7 +2439,6 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
3001
2439
|
_nativeSubHeaderView.transform = CGAffineTransformIdentity;
|
|
3002
2440
|
[_headerView removeFromSuperview];
|
|
3003
2441
|
[_stickyHeaderView removeFromSuperview];
|
|
3004
|
-
[_topOverlayView removeFromSuperview];
|
|
3005
2442
|
for (UIViewController *controller in _pageControllers) {
|
|
3006
2443
|
[controller.view removeFromSuperview];
|
|
3007
2444
|
}
|
|
@@ -3009,9 +2446,6 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
3009
2446
|
[_pageControllers removeAllObjects];
|
|
3010
2447
|
_headerView = nil;
|
|
3011
2448
|
_stickyHeaderView = nil;
|
|
3012
|
-
_topOverlayView = nil;
|
|
3013
|
-
_topOverlayHostView.hidden = YES;
|
|
3014
|
-
[self updateTopScrollEdgeForScrollView:nil];
|
|
3015
2449
|
_pageViewController.dataSource = nil;
|
|
3016
2450
|
_pageViewController.delegate = nil;
|
|
3017
2451
|
_pagerScrollView.delegate = nil;
|
|
@@ -3044,13 +2478,6 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
3044
2478
|
_pendingInitialPage = 0;
|
|
3045
2479
|
_headerHeight = 0;
|
|
3046
2480
|
_stickyHeaderHeight = 0;
|
|
3047
|
-
_topOverlayHeight = 0;
|
|
3048
|
-
_externalTopOverlayTag = 0;
|
|
3049
|
-
_externalTopOverlayView = nil;
|
|
3050
|
-
_externalTopOverlayHeight = 0;
|
|
3051
|
-
_externalOuterPageActive = NO;
|
|
3052
|
-
_externalOuterTransitioning = NO;
|
|
3053
|
-
_topScrollEdgeHard = NO;
|
|
3054
2481
|
_nativeTabBarHeight = 44;
|
|
3055
2482
|
_nativeSubHeaderHeight = 74;
|
|
3056
2483
|
_headerOffset = 0;
|
|
@@ -3074,7 +2501,6 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
3074
2501
|
_pendingGoToIndex = -1;
|
|
3075
2502
|
_pendingGoToAnimated = YES;
|
|
3076
2503
|
_needsSlotRebuild = NO;
|
|
3077
|
-
_deferTopEdgeSlotRebuild = NO;
|
|
3078
2504
|
_hasAppliedInitialPage = NO;
|
|
3079
2505
|
// OneKey patch: Fabric retains old props when recycling this view.
|
|
3080
2506
|
_needsPropsReapply = YES;
|
|
@@ -3091,9 +2517,6 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
3091
2517
|
{
|
|
3092
2518
|
const auto &oldViewProps = *std::static_pointer_cast<const RNCCollapsiblePagerViewProps>(_props);
|
|
3093
2519
|
const auto &newViewProps = *std::static_pointer_cast<const RNCCollapsiblePagerViewProps>(props);
|
|
3094
|
-
_applyingTopOverlayInsetChange =
|
|
3095
|
-
oldViewProps.topScrollEdgeHard != newViewProps.topScrollEdgeHard ||
|
|
3096
|
-
oldViewProps.topOverlayHeight != newViewProps.topOverlayHeight;
|
|
3097
2520
|
|
|
3098
2521
|
if (_needsPropsReapply || oldViewProps.initialPage != newViewProps.initialPage) {
|
|
3099
2522
|
_pendingInitialPage = MAX(0, newViewProps.initialPage);
|
|
@@ -3143,43 +2566,6 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
3143
2566
|
_stickyHeaderHeight = MAX(0, newViewProps.stickyHeaderHeight);
|
|
3144
2567
|
insetsChanged = YES;
|
|
3145
2568
|
}
|
|
3146
|
-
if (_needsPropsReapply || oldViewProps.topScrollEdgeHard != newViewProps.topScrollEdgeHard) {
|
|
3147
|
-
_topScrollEdgeHard = newViewProps.topScrollEdgeHard;
|
|
3148
|
-
if (oldViewProps.topScrollEdgeHard || newViewProps.topScrollEdgeHard) {
|
|
3149
|
-
_deferTopEdgeSlotRebuild = YES;
|
|
3150
|
-
[self rebuildSlots];
|
|
3151
|
-
NSUInteger generation = _generation;
|
|
3152
|
-
dispatch_async(dispatch_get_main_queue(), ^{
|
|
3153
|
-
if (self->_generation != generation || self->_isBeingRecycled ||
|
|
3154
|
-
!self->_deferTopEdgeSlotRebuild) return;
|
|
3155
|
-
self->_deferTopEdgeSlotRebuild = NO;
|
|
3156
|
-
[self rebuildSlots];
|
|
3157
|
-
});
|
|
3158
|
-
}
|
|
3159
|
-
insetsChanged = YES;
|
|
3160
|
-
}
|
|
3161
|
-
if (_needsPropsReapply ||
|
|
3162
|
-
oldViewProps.topOverlayColorScheme != newViewProps.topOverlayColorScheme) {
|
|
3163
|
-
NSString *nextScheme = RCTNSStringFromString(newViewProps.topOverlayColorScheme);
|
|
3164
|
-
if (self.hasFixedTopOverlay && _topScrollEdgeHard &&
|
|
3165
|
-
_topOverlayColorScheme != nil &&
|
|
3166
|
-
![_topOverlayColorScheme isEqualToString:nextScheme]) {
|
|
3167
|
-
_pendingTopOverlayAppearanceCommit = YES;
|
|
3168
|
-
[self updateTopScrollEdgeForScrollView:nil];
|
|
3169
|
-
}
|
|
3170
|
-
_topOverlayColorScheme = nextScheme;
|
|
3171
|
-
[self syncScrollEdgeAppearance];
|
|
3172
|
-
}
|
|
3173
|
-
if (_needsPropsReapply || oldViewProps.topOverlayHeight != newViewProps.topOverlayHeight) {
|
|
3174
|
-
_topOverlayHeight = MAX(0, newViewProps.topOverlayHeight);
|
|
3175
|
-
insetsChanged = YES;
|
|
3176
|
-
}
|
|
3177
|
-
if (_needsPropsReapply ||
|
|
3178
|
-
oldViewProps.externalTopOverlayTag != newViewProps.externalTopOverlayTag) {
|
|
3179
|
-
_externalTopOverlayTag = newViewProps.externalTopOverlayTag;
|
|
3180
|
-
[self registerExternalOuterPager];
|
|
3181
|
-
insetsChanged = [self resolveExternalTopOverlay] || insetsChanged;
|
|
3182
|
-
}
|
|
3183
2569
|
if (_needsPropsReapply || oldViewProps.pageKeys != newViewProps.pageKeys) {
|
|
3184
2570
|
NSString *json = RCTNSStringFromString(newViewProps.pageKeys);
|
|
3185
2571
|
NSData *data = [json dataUsingEncoding:NSUTF8StringEncoding];
|
|
@@ -3247,23 +2633,17 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
3247
2633
|
|
|
3248
2634
|
_needsPropsReapply = NO;
|
|
3249
2635
|
[super updateProps:props oldProps:oldProps];
|
|
3250
|
-
[self updateTopScrollEdgeForScrollView:_observedScrollView];
|
|
3251
2636
|
if (insetsChanged) {
|
|
3252
2637
|
[self reapplyInsetsToObservedScrollView];
|
|
3253
2638
|
[self setNeedsLayout];
|
|
3254
2639
|
}
|
|
3255
|
-
_applyingTopOverlayInsetChange = NO;
|
|
3256
2640
|
if (!_nativeTabBarView.hidden) {
|
|
3257
|
-
[
|
|
2641
|
+
[_sharedHeaderHostView bringSubviewToFront:_nativeTabBarView];
|
|
3258
2642
|
}
|
|
3259
2643
|
if (!_nativeSubHeaderView.hidden) {
|
|
3260
|
-
[
|
|
2644
|
+
[_sharedHeaderHostView bringSubviewToFront:_nativeSubHeaderView];
|
|
3261
2645
|
}
|
|
3262
2646
|
[_sharedHeaderHostView.superview bringSubviewToFront:_sharedHeaderHostView];
|
|
3263
|
-
if (_stickyHeaderIsPinned) {
|
|
3264
|
-
[_pinnedStickyHostView.superview bringSubviewToFront:_pinnedStickyHostView];
|
|
3265
|
-
}
|
|
3266
|
-
if (self.hasFixedTopOverlay) [_containerView bringSubviewToFront:_topOverlayHostView];
|
|
3267
2647
|
}
|
|
3268
2648
|
|
|
3269
2649
|
#pragma mark - Collapsible scroll coordination
|
|
@@ -3497,17 +2877,21 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
3497
2877
|
return;
|
|
3498
2878
|
}
|
|
3499
2879
|
|
|
2880
|
+
[self offsetDiag:@"observer-candidate" page:_currentIndex scroll:candidate];
|
|
3500
2881
|
BOOL replacingCurrentScrollView = _observingContentOffset &&
|
|
3501
2882
|
(!_nativeSmoothHeaderScrollEnabled || [_observedPageKey isEqualToString:self.currentPageKey]);
|
|
3502
2883
|
[self detachScrollObserver];
|
|
3503
2884
|
if (replacingCurrentScrollView) {
|
|
3504
2885
|
// Legacy replacement discards body state; smooth replacement waits for layout.
|
|
2886
|
+
[self offsetDiag:@"observer-replacement-cache-before" page:_currentIndex scroll:candidate];
|
|
3505
2887
|
if (!_nativeSmoothHeaderScrollEnabled) _pageOffsets[self.currentPageKey] = @(_headerOffset);
|
|
2888
|
+
[self offsetDiag:@"observer-replacement-cache-after" page:_currentIndex scroll:candidate];
|
|
3506
2889
|
}
|
|
3507
2890
|
_observedScrollView = candidate;
|
|
3508
2891
|
_observedPageKey = [self.currentPageKey copy];
|
|
3509
2892
|
_observedPageIndex = _currentIndex;
|
|
3510
2893
|
_observedPageGeneration = _generation;
|
|
2894
|
+
[self offsetDiag:@"observer-attached-before-restore" page:_currentIndex scroll:candidate];
|
|
3511
2895
|
[self applyInsetsToScrollView:candidate pageIndex:_currentIndex restore:YES];
|
|
3512
2896
|
[candidate addObserver:self
|
|
3513
2897
|
forKeyPath:@"contentOffset"
|
|
@@ -3525,7 +2909,6 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
3525
2909
|
_observingContentOffset = YES;
|
|
3526
2910
|
_needsScrollObserverReattachAfterMount = NO;
|
|
3527
2911
|
_currentLogicalOffset = candidate.contentOffset.y + candidate.contentInset.top;
|
|
3528
|
-
[self updateTopScrollEdgeForScrollView:candidate];
|
|
3529
2912
|
[self attachSharedHeadersToScrollView:candidate];
|
|
3530
2913
|
[self updateSharedHeaderPressCancellationGesture];
|
|
3531
2914
|
[self updateHeaderSettledStateForceBusy:NO];
|
|
@@ -3533,9 +2916,6 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
3533
2916
|
|
|
3534
2917
|
- (void)detachScrollObserver
|
|
3535
2918
|
{
|
|
3536
|
-
[self cancelTopInsetReboundCheck];
|
|
3537
|
-
[self restorePinnedStickyHeader];
|
|
3538
|
-
[self updateTopScrollEdgeForScrollView:nil];
|
|
3539
2919
|
[self cancelHeaderSettledCheck];
|
|
3540
2920
|
_headerCommandOwner = nil;
|
|
3541
2921
|
_headerSettledGeometry = nil;
|
|
@@ -3545,6 +2925,7 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
3545
2925
|
UIScrollView *scrollView = _observedScrollView;
|
|
3546
2926
|
if (scrollView != nil) {
|
|
3547
2927
|
[scrollView.panGestureRecognizer removeTarget:self action:@selector(observedListPanChanged:)];
|
|
2928
|
+
[self offsetDiag:@"detach-save-before" page:_currentIndex scroll:scrollView];
|
|
3548
2929
|
NSString *ownerKey = _nativeSmoothHeaderScrollEnabled ? _observedPageKey : self.currentPageKey;
|
|
3549
2930
|
BOOL ownerKeyExists = ownerKey != nil && ([_pageKeys containsObject:ownerKey] ||
|
|
3550
2931
|
(_observedPageIndex >= 0 && _observedPageIndex < _pageControllers.count &&
|
|
@@ -3552,6 +2933,7 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
3552
2933
|
if (ownerKey != nil && !_nativeSmoothHeaderScrollEnabled) {
|
|
3553
2934
|
_pageOffsets[ownerKey] = @(scrollView.contentOffset.y + scrollView.contentInset.top);
|
|
3554
2935
|
}
|
|
2936
|
+
[self offsetDiag:@"detach-save-after" page:_currentIndex scroll:scrollView];
|
|
3555
2937
|
if (_observingContentOffset) {
|
|
3556
2938
|
[scrollView removeObserver:self
|
|
3557
2939
|
forKeyPath:@"contentOffset"
|
|
@@ -3593,9 +2975,6 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
3593
2975
|
removeGestureRecognizer:_sharedHeaderOuterPagerGesture];
|
|
3594
2976
|
}
|
|
3595
2977
|
_sharedHeaderOuterPagerGesture.blockedPagerGestures = nil;
|
|
3596
|
-
_sharedHeaderOuterPagerGesture.trackedTouch = nil;
|
|
3597
|
-
_sharedHeaderOuterPagerGesture.protectsNestedBody = NO;
|
|
3598
|
-
_sharedHeaderOuterPagerGesture.cancelsTouchesInView = YES;
|
|
3599
2978
|
_sharedHeaderPressCancellationGestureHost = nil;
|
|
3600
2979
|
_reactTouchHandler = nil;
|
|
3601
2980
|
}
|
|
@@ -3645,7 +3024,7 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
3645
3024
|
}
|
|
3646
3025
|
}
|
|
3647
3026
|
if (_sharedHeaderPressCancellationGesture.view == gestureHost &&
|
|
3648
|
-
_sharedHeaderOuterPagerGesture.view ==
|
|
3027
|
+
_sharedHeaderOuterPagerGesture.view == _sharedHeaderHostView &&
|
|
3649
3028
|
_reactTouchHandler == reactTouchHandler) {
|
|
3650
3029
|
_sharedHeaderOuterPagerGesture.blockedPagerGestures = outerPagerGestures;
|
|
3651
3030
|
return;
|
|
@@ -3687,7 +3066,7 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
3687
3066
|
_reactTouchHandler = reactTouchHandler;
|
|
3688
3067
|
_sharedHeaderPressCancellationGestureHost = gestureHost;
|
|
3689
3068
|
[gestureHost addGestureRecognizer:_sharedHeaderPressCancellationGesture];
|
|
3690
|
-
[
|
|
3069
|
+
[_sharedHeaderHostView addGestureRecognizer:_sharedHeaderOuterPagerGesture];
|
|
3691
3070
|
RNCCollapsiblePagerLog([NSString stringWithFormat:
|
|
3692
3071
|
@"press-cancel-bridge attached=1 outer-pagers=%lu",
|
|
3693
3072
|
(unsigned long)outerPagerGestures.count]);
|
|
@@ -3759,11 +3138,6 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
3759
3138
|
|
|
3760
3139
|
- (void)observedListPanChanged:(UIPanGestureRecognizer *)recognizer
|
|
3761
3140
|
{
|
|
3762
|
-
if (recognizer == _pendingTopInsetReboundScrollView.panGestureRecognizer &&
|
|
3763
|
-
(recognizer.state == UIGestureRecognizerStateBegan ||
|
|
3764
|
-
recognizer.state == UIGestureRecognizerStateChanged)) {
|
|
3765
|
-
[self cancelTopInsetReboundCheck];
|
|
3766
|
-
}
|
|
3767
3141
|
if (recognizer == _observedScrollView.panGestureRecognizer) {
|
|
3768
3142
|
[self updateHeaderSettledStateForceBusy:
|
|
3769
3143
|
recognizer.state == UIGestureRecognizerStateBegan || recognizer.state == UIGestureRecognizerStateChanged];
|
|
@@ -3831,7 +3205,7 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
3831
3205
|
[_managedRefreshControls removeObjectForKey:scrollView];
|
|
3832
3206
|
if (current != nil) [_managedRefreshControls setObject:current forKey:scrollView];
|
|
3833
3207
|
}
|
|
3834
|
-
[RNCRefreshControlOffsetState setOffset:
|
|
3208
|
+
[RNCRefreshControlOffsetState setOffset:_headerHeight + _stickyHeaderHeight
|
|
3835
3209
|
forControl:current owner:self];
|
|
3836
3210
|
}
|
|
3837
3211
|
|
|
@@ -3845,53 +3219,6 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
3845
3219
|
[_managedRefreshControls removeObjectForKey:scrollView];
|
|
3846
3220
|
}
|
|
3847
3221
|
|
|
3848
|
-
- (void)cancelTopInsetReboundCheck
|
|
3849
|
-
{
|
|
3850
|
-
[_topInsetReboundTimer invalidate];
|
|
3851
|
-
_topInsetReboundTimer = nil;
|
|
3852
|
-
_pendingTopInsetReboundScrollView = nil;
|
|
3853
|
-
_pendingTopInsetReboundPageKey = nil;
|
|
3854
|
-
}
|
|
3855
|
-
|
|
3856
|
-
- (void)scheduleTopInsetReboundCheck
|
|
3857
|
-
{
|
|
3858
|
-
if (_pendingTopInsetReboundScrollView == nil ||
|
|
3859
|
-
_pendingTopInsetReboundScrollView != _observedScrollView) return;
|
|
3860
|
-
[_topInsetReboundTimer invalidate];
|
|
3861
|
-
__weak __typeof__(self) weakSelf = self;
|
|
3862
|
-
_topInsetReboundTimer = [NSTimer scheduledTimerWithTimeInterval:0.15 repeats:NO block:^(NSTimer *timer) {
|
|
3863
|
-
__strong __typeof__(weakSelf) self = weakSelf;
|
|
3864
|
-
if (self == nil || self->_topInsetReboundTimer != timer) return;
|
|
3865
|
-
self->_topInsetReboundTimer = nil;
|
|
3866
|
-
UIScrollView *scrollView = self->_pendingTopInsetReboundScrollView;
|
|
3867
|
-
if (scrollView == nil || scrollView != self->_observedScrollView ||
|
|
3868
|
-
self->_pendingTopInsetReboundGeneration != self->_generation ||
|
|
3869
|
-
![self->_pendingTopInsetReboundPageKey isEqualToString:self.currentPageKey] ||
|
|
3870
|
-
self->_isBeingRecycled || self.window == nil ||
|
|
3871
|
-
self->_transitioning || self->_isPagerDragging ||
|
|
3872
|
-
self->_headerCommandOwner == scrollView || self->_pagerTopPageKey != nil) {
|
|
3873
|
-
[self cancelTopInsetReboundCheck];
|
|
3874
|
-
return;
|
|
3875
|
-
}
|
|
3876
|
-
UIGestureRecognizerState pan = scrollView.panGestureRecognizer.state;
|
|
3877
|
-
if (scrollView.refreshControl.isRefreshing || scrollView.isDragging ||
|
|
3878
|
-
scrollView.isDecelerating || scrollView.isTracking ||
|
|
3879
|
-
pan == UIGestureRecognizerStateBegan || pan == UIGestureRecognizerStateChanged ||
|
|
3880
|
-
self->_syntheticPageRestore || self->_transitionPageOffsets != nil) {
|
|
3881
|
-
[self scheduleTopInsetReboundCheck];
|
|
3882
|
-
return;
|
|
3883
|
-
}
|
|
3884
|
-
CGFloat minimumOffset = -scrollView.adjustedContentInset.top;
|
|
3885
|
-
[self cancelTopInsetReboundCheck];
|
|
3886
|
-
if (scrollView.contentOffset.y < minimumOffset - 0.5) {
|
|
3887
|
-
// UIKit can finish a refresh rebound at the inset that preceded an overlay resize.
|
|
3888
|
-
self->_correctingTopInsetRebound = YES;
|
|
3889
|
-
[scrollView setContentOffset:CGPointMake(scrollView.contentOffset.x, minimumOffset) animated:NO];
|
|
3890
|
-
self->_correctingTopInsetRebound = NO;
|
|
3891
|
-
}
|
|
3892
|
-
}];
|
|
3893
|
-
}
|
|
3894
|
-
|
|
3895
3222
|
// OneKey patch: release observers, headers and saved state while the scroll view
|
|
3896
3223
|
// still represents the old list, before Fabric applies its next owner's props.
|
|
3897
3224
|
- (void)restoreScrollViewState:(UIScrollView *)scrollView resetSavedOffset:(BOOL)resetSavedOffset
|
|
@@ -3900,7 +3227,9 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
3900
3227
|
[self releaseRefreshControlForScrollView:scrollView];
|
|
3901
3228
|
if (scrollView == _observedScrollView) {
|
|
3902
3229
|
[self detachScrollObserver];
|
|
3230
|
+
[self offsetDiag:resetSavedOffset ? @"release-reset-before" : @"release-retain-before" page:_currentIndex scroll:scrollView];
|
|
3903
3231
|
if (resetSavedOffset && !_nativeSmoothHeaderScrollEnabled) _pageOffsets[self.currentPageKey] = @(_headerOffset);
|
|
3232
|
+
[self offsetDiag:@"release-reset-after" page:_currentIndex scroll:scrollView];
|
|
3904
3233
|
}
|
|
3905
3234
|
if (scrollView == _sharedHeaderScrollView) {
|
|
3906
3235
|
[self restoreSharedHeadersToContainer];
|
|
@@ -3920,8 +3249,10 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
3920
3249
|
[_originalDirectionalLockEnabled objectForKey:scrollView].boolValue;
|
|
3921
3250
|
scrollView.contentInsetAdjustmentBehavior = (UIScrollViewContentInsetAdjustmentBehavior)
|
|
3922
3251
|
[_originalInsetAdjustmentBehavior objectForKey:scrollView].integerValue;
|
|
3252
|
+
[self offsetDiag:@"release-original-offset-before" page:_currentIndex scroll:scrollView];
|
|
3923
3253
|
[scrollView setContentOffset:CGPointMake(scrollView.contentOffset.x, logicalOffset - original.top)
|
|
3924
3254
|
animated:NO];
|
|
3255
|
+
[self offsetDiag:@"release-original-offset-after" page:_currentIndex scroll:scrollView];
|
|
3925
3256
|
[_originalInsets removeObjectForKey:scrollView];
|
|
3926
3257
|
[_appliedTopInsets removeObjectForKey:scrollView];
|
|
3927
3258
|
[_originalIndicatorInsets removeObjectForKey:scrollView];
|
|
@@ -3952,6 +3283,7 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
3952
3283
|
{
|
|
3953
3284
|
// Smooth pages retain their complete offset while replacement identity and
|
|
3954
3285
|
// layout settle. Legacy pages retain the historical header-only policy.
|
|
3286
|
+
[self offsetDiag:restore ? @"restore-enter" : @"insets-enter" page:pageIndex scroll:scrollView];
|
|
3955
3287
|
NSString *pageKey = [self pageKeyForIndex:pageIndex];
|
|
3956
3288
|
RNCCollapsiblePagerReleasedScrollState *released = _releasedPageScrollStates[pageKey];
|
|
3957
3289
|
BOOL deferredReleasedIdentity = NO;
|
|
@@ -3997,8 +3329,13 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
3997
3329
|
deferredReleasedIdentity = now - released.pendingFallbackDetectedAt <
|
|
3998
3330
|
RNCCollapsiblePagerFallbackDebounceInterval;
|
|
3999
3331
|
}
|
|
3332
|
+
#if DEBUG
|
|
3333
|
+
[self offsetDiag:[NSString stringWithFormat:@"released-identity-match=%d-deferred=%d-oldTag=%ld-oldScroll=%p", sameList, deferredReleasedIdentity, (long)released.componentTag, (__bridge void *)released.scrollView] page:pageIndex scroll:scrollView];
|
|
3334
|
+
#endif
|
|
4000
3335
|
if (!deferredReleasedIdentity) {
|
|
3336
|
+
[self offsetDiag:@"released-identity-cache-before" page:pageIndex scroll:scrollView];
|
|
4001
3337
|
if (!sameList && !_nativeSmoothHeaderScrollEnabled) _pageOffsets[pageKey] = @(_headerOffset);
|
|
3338
|
+
[self offsetDiag:@"released-identity-cache-after" page:pageIndex scroll:scrollView];
|
|
4002
3339
|
[_releasedPageScrollStates removeObjectForKey:pageKey];
|
|
4003
3340
|
}
|
|
4004
3341
|
}
|
|
@@ -4023,24 +3360,22 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
4023
3360
|
// suppress its later vertical movement while the pager is still pending.
|
|
4024
3361
|
scrollView.directionalLockEnabled = _nativeSmoothHeaderScrollEnabled
|
|
4025
3362
|
? NO : [_originalDirectionalLockEnabled objectForKey:scrollView].boolValue;
|
|
4026
|
-
[self updateNativeScrollerViewport:scrollView stickyHeight:_stickyHeaderHeight
|
|
3363
|
+
[self updateNativeScrollerViewport:scrollView stickyHeight:_stickyHeaderHeight];
|
|
4027
3364
|
[self updateRefreshControlForScrollView:scrollView];
|
|
4028
3365
|
CGFloat previousTopInset = scrollView.contentInset.top;
|
|
4029
3366
|
CGFloat previousLogicalOffset = scrollView.contentOffset.y + previousTopInset;
|
|
4030
|
-
// Preserve UIKit's rebound after refresh while the content is beyond its top inset.
|
|
4031
|
-
BOOL wasReturningFromPull = scrollView.contentOffset.y < -scrollView.adjustedContentInset.top - 0.5;
|
|
4032
3367
|
NSNumber *appliedTop = [_appliedTopInsets objectForKey:scrollView];
|
|
4033
3368
|
// UIRefreshControl owns its temporary top inset, including while ending.
|
|
4034
3369
|
CGFloat refreshInset = appliedTop != nil && scrollView.refreshControl != nil
|
|
4035
3370
|
? MAX(0, previousTopInset - appliedTop.doubleValue) : 0;
|
|
4036
3371
|
UIEdgeInsets next = original;
|
|
4037
|
-
next.top +=
|
|
3372
|
+
next.top += _headerHeight + _stickyHeaderHeight;
|
|
4038
3373
|
CGFloat pagerTopInset = next.top;
|
|
4039
3374
|
next.top += refreshInset;
|
|
4040
3375
|
[_appliedTopInsets setObject:@(pagerTopInset) forKey:scrollView];
|
|
4041
3376
|
// Short pages still need enough range to collapse the header; long pages
|
|
4042
3377
|
// must end at the last row rather than leave a header-sized blank footer.
|
|
4043
|
-
next.bottom += MAX(0, scrollView.bounds.size.height - _stickyHeaderHeight
|
|
3378
|
+
next.bottom += MAX(0, scrollView.bounds.size.height - _stickyHeaderHeight
|
|
4044
3379
|
- original.top - original.bottom - scrollView.contentSize.height);
|
|
4045
3380
|
if (UIEdgeInsetsEqualToEdgeInsets(scrollView.contentInset, next) && !restore) {
|
|
4046
3381
|
// UICollectionView may report contentSize during a bounce without changing
|
|
@@ -4050,7 +3385,9 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
4050
3385
|
}
|
|
4051
3386
|
BOOL previousSyntheticRestore = _syntheticPageRestore;
|
|
4052
3387
|
if (_nativeSmoothHeaderScrollEnabled || [_alignedBodyKeys containsObject:pageKey]) _syntheticPageRestore = YES;
|
|
3388
|
+
[self offsetDiag:@"inset-assignment-before" page:pageIndex scroll:scrollView];
|
|
4053
3389
|
scrollView.contentInset = next;
|
|
3390
|
+
[self offsetDiag:@"inset-assignment-after" page:pageIndex scroll:scrollView];
|
|
4054
3391
|
UIEdgeInsets indicatorInsets = scrollView.verticalScrollIndicatorInsets;
|
|
4055
3392
|
indicatorInsets.top = pagerTopInset;
|
|
4056
3393
|
scrollView.verticalScrollIndicatorInsets = indicatorInsets;
|
|
@@ -4082,6 +3419,9 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
4082
3419
|
} else {
|
|
4083
3420
|
restoredLogicalOffset = deferredReleasedIdentity || saved == nil ? _headerOffset : saved.doubleValue;
|
|
4084
3421
|
}
|
|
3422
|
+
#if DEBUG
|
|
3423
|
+
[self offsetDiag:[NSString stringWithFormat:@"restore-candidate-saved=%.4f-headerAlignedLogical=%.4f", saved.doubleValue, restoredLogicalOffset] page:pageIndex scroll:scrollView];
|
|
3424
|
+
#endif
|
|
4085
3425
|
intendedLogicalOffset = restoredLogicalOffset;
|
|
4086
3426
|
// Cancellation restores the visible source, while retaining its unreachable reading intent.
|
|
4087
3427
|
if (_nativeSmoothHeaderScrollEnabled && _headerOffset >= _headerHeight &&
|
|
@@ -4094,6 +3434,9 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
4094
3434
|
}
|
|
4095
3435
|
// An inactive list may shrink after its offset observer was detached.
|
|
4096
3436
|
// Do not overwrite its corrected offset with a now-unreachable cached one.
|
|
3437
|
+
#if DEBUG
|
|
3438
|
+
[self offsetDiag:[NSString stringWithFormat:@"restore-clamp-before-candidate=%.4f-max=%.4f", targetOffset, MAX(-next.top, scrollView.contentSize.height - scrollView.bounds.size.height + next.bottom)] page:pageIndex scroll:scrollView];
|
|
3439
|
+
#endif
|
|
4097
3440
|
targetOffset = RNCLimitRestoredScrollOffset(
|
|
4098
3441
|
targetOffset,
|
|
4099
3442
|
scrollView.contentSize.height,
|
|
@@ -4102,17 +3445,13 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
4102
3445
|
next.bottom
|
|
4103
3446
|
);
|
|
4104
3447
|
}
|
|
3448
|
+
#if DEBUG
|
|
3449
|
+
[self offsetDiag:[NSString stringWithFormat:@"restore-final-target=%.4f-restore=%d", targetOffset, restore] page:pageIndex scroll:scrollView];
|
|
3450
|
+
#endif
|
|
4105
3451
|
// A bottom-inset change must not cancel UIKit's refresh or bounce settlement.
|
|
4106
|
-
if (restore ||
|
|
3452
|
+
if (restore || previousTopInset != next.top) {
|
|
4107
3453
|
[scrollView setContentOffset:CGPointMake(scrollView.contentOffset.x, targetOffset) animated:NO];
|
|
4108
3454
|
}
|
|
4109
|
-
if (_applyingTopOverlayInsetChange && !restore && wasReturningFromPull &&
|
|
4110
|
-
previousTopInset != next.top && scrollView == _observedScrollView) {
|
|
4111
|
-
_pendingTopInsetReboundScrollView = scrollView;
|
|
4112
|
-
_pendingTopInsetReboundPageKey = [pageKey copy];
|
|
4113
|
-
_pendingTopInsetReboundGeneration = _generation;
|
|
4114
|
-
[self scheduleTopInsetReboundCheck];
|
|
4115
|
-
}
|
|
4116
3455
|
if (_nativeSmoothHeaderScrollEnabled && restore && targetOffset + next.top + 0.5 < intendedLogicalOffset) {
|
|
4117
3456
|
[_pendingPageRestoreKeys addObject:pageKey];
|
|
4118
3457
|
}
|
|
@@ -4122,6 +3461,7 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
4122
3461
|
if (!_nativeSmoothHeaderScrollEnabled) [self updateHeaderForScrollView:scrollView];
|
|
4123
3462
|
else [self applyHeaderOffset];
|
|
4124
3463
|
}
|
|
3464
|
+
[self offsetDiag:@"restore-post" page:pageIndex scroll:scrollView];
|
|
4125
3465
|
}
|
|
4126
3466
|
|
|
4127
3467
|
- (void)updateNativeScrollerViewport:(UIScrollView *)scrollView stickyHeight:(CGFloat)height
|
|
@@ -4138,7 +3478,6 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
4138
3478
|
_observedPageKey == nil || ![_observedPageKey isEqualToString:self.currentPageKey] ||
|
|
4139
3479
|
_observedPageIndex != _currentIndex || _observedPageGeneration != _generation ||
|
|
4140
3480
|
_transitioning || _isPagerDragging || _transitionPageOffsets != nil || _syntheticPageRestore) return;
|
|
4141
|
-
[self cancelTopInsetReboundCheck];
|
|
4142
3481
|
NSInteger phase = [notification.userInfo[@"phase"] integerValue];
|
|
4143
3482
|
[self updateHeaderSettledStateForceBusy:NO];
|
|
4144
3483
|
if (phase == 1) _headerCommandOwner = scrollView;
|
|
@@ -4171,6 +3510,7 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
4171
3510
|
_headerOffset = 0;
|
|
4172
3511
|
[self applyHeaderOffset];
|
|
4173
3512
|
}
|
|
3513
|
+
[self offsetDiag:@"list-command-body-takeover" page:_currentIndex scroll:scrollView];
|
|
4174
3514
|
}
|
|
4175
3515
|
|
|
4176
3516
|
- (void)nativeScrollerWillReceiveScrollCommand:(RNCNativeScrollerComponentView *)scroller
|
|
@@ -4182,12 +3522,12 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
4182
3522
|
_observedPageIndex != _currentIndex || _currentIndex < 0 || _currentIndex >= _pageControllers.count ||
|
|
4183
3523
|
_observedPageGeneration != _generation || _transitioning || _isPagerDragging ||
|
|
4184
3524
|
_transitionPageOffsets != nil || _syntheticPageRestore) return;
|
|
4185
|
-
[self cancelTopInsetReboundCheck];
|
|
4186
3525
|
if (!_dispatchingPagerTop) {
|
|
4187
3526
|
[self cancelPagerTop];
|
|
4188
3527
|
[_alignedBodyKeys removeObject:ownerKey];
|
|
4189
3528
|
}
|
|
4190
3529
|
if (!_nativeSmoothHeaderScrollEnabled) return;
|
|
3530
|
+
[self offsetDiag:@"command-pending-cancel-before" page:_observedPageIndex scroll:scrollView];
|
|
4191
3531
|
[_pendingPageRestoreKeys removeObject:ownerKey];
|
|
4192
3532
|
_currentLogicalOffset = scrollView.contentOffset.y + scrollView.contentInset.top;
|
|
4193
3533
|
[_commandBodyKeys removeObject:ownerKey];
|
|
@@ -4196,6 +3536,7 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
4196
3536
|
[_displayBodyOverrides removeObjectForKey:ownerKey];
|
|
4197
3537
|
_pageOffsets[ownerKey] = @(MAX(_currentLogicalOffset - _headerHeight, 0));
|
|
4198
3538
|
[self updateHeaderForScrollView:scrollView];
|
|
3539
|
+
[self offsetDiag:@"command-pending-cancel-after" page:_observedPageIndex scroll:scrollView];
|
|
4199
3540
|
}
|
|
4200
3541
|
|
|
4201
3542
|
|
|
@@ -4257,14 +3598,6 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
4257
3598
|
return;
|
|
4258
3599
|
}
|
|
4259
3600
|
if (context == RNCCollapsiblePagerContentOffsetContext && object == _observedScrollView) {
|
|
4260
|
-
if (_pendingTopInsetReboundScrollView == object &&
|
|
4261
|
-
([keyPath isEqualToString:@"contentOffset"] || [keyPath isEqualToString:@"contentInset"])) {
|
|
4262
|
-
if (((UIScrollView *)object).panGestureRecognizer.state == UIGestureRecognizerStateChanged) {
|
|
4263
|
-
[self cancelTopInsetReboundCheck];
|
|
4264
|
-
} else {
|
|
4265
|
-
[self scheduleTopInsetReboundCheck];
|
|
4266
|
-
}
|
|
4267
|
-
}
|
|
4268
3601
|
if (![change[NSKeyValueChangeOldKey] isEqual:change[NSKeyValueChangeNewKey]]) {
|
|
4269
3602
|
[self updateHeaderSettledStateForceBusy:YES];
|
|
4270
3603
|
}
|
|
@@ -4329,12 +3662,18 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
4329
3662
|
}
|
|
4330
3663
|
UIScrollView *scrollView = (UIScrollView *)object;
|
|
4331
3664
|
_currentLogicalOffset = scrollView.contentOffset.y + scrollView.contentInset.top;
|
|
4332
|
-
|
|
3665
|
+
#if DEBUG
|
|
3666
|
+
BOOL offsetDiagChanged = _pageOffsets[self.currentPageKey] == nil || _pageOffsets[self.currentPageKey].doubleValue != (_nativeSmoothHeaderScrollEnabled ? MAX(_currentLogicalOffset - _headerHeight, 0) : _currentLogicalOffset);
|
|
3667
|
+
if (offsetDiagChanged) [self offsetDiag:@"kvo-cache-before" page:_currentIndex scroll:scrollView];
|
|
3668
|
+
#endif
|
|
4333
3669
|
if ([_alignedBodyKeys containsObject:_observedPageKey] ||
|
|
4334
3670
|
(_nativeSmoothHeaderScrollEnabled && scrollView.panGestureRecognizer.state != UIGestureRecognizerStateChanged &&
|
|
4335
3671
|
!scrollView.isDecelerating && ![_commandBodyKeys containsObject:_observedPageKey])) return;
|
|
4336
3672
|
_pageOffsets[_nativeSmoothHeaderScrollEnabled ? _observedPageKey : self.currentPageKey] =
|
|
4337
3673
|
@(_nativeSmoothHeaderScrollEnabled ? MAX(_currentLogicalOffset - _headerHeight, 0) : _currentLogicalOffset);
|
|
3674
|
+
#if DEBUG
|
|
3675
|
+
if (offsetDiagChanged) [self offsetDiag:@"kvo-cache-after" page:_currentIndex scroll:scrollView];
|
|
3676
|
+
#endif
|
|
4338
3677
|
[self updateHeaderForScrollView:scrollView];
|
|
4339
3678
|
return;
|
|
4340
3679
|
}
|
|
@@ -4375,22 +3714,17 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
4375
3714
|
? MAX(0, scrollView.contentInset.top - appliedTop.doubleValue) : 0;
|
|
4376
3715
|
CGFloat pinnedTranslation = MAX(0, _currentLogicalOffset - _headerHeight - refreshInset);
|
|
4377
3716
|
CGAffineTransform stickyTransform = CGAffineTransformMakeTranslation(0, pinnedTranslation);
|
|
4378
|
-
|
|
4379
|
-
|
|
4380
|
-
|
|
4381
|
-
_nativeSubHeaderView.transform = _stickyHeaderIsPinned ? CGAffineTransformIdentity : stickyTransform;
|
|
4382
|
-
[self updateScrollEdgeContentMasks];
|
|
3717
|
+
_stickyHeaderView.transform = stickyTransform;
|
|
3718
|
+
_nativeTabBarView.transform = stickyTransform;
|
|
3719
|
+
_nativeSubHeaderView.transform = stickyTransform;
|
|
4383
3720
|
return;
|
|
4384
3721
|
}
|
|
4385
|
-
[self updatePinnedStickyHeader];
|
|
4386
3722
|
CGAffineTransform collapseTransform = CGAffineTransformMakeTranslation(0, -_headerOffset);
|
|
4387
3723
|
_sharedHeaderHostView.transform = collapseTransform;
|
|
4388
3724
|
_headerView.transform = CGAffineTransformIdentity;
|
|
4389
3725
|
_stickyHeaderView.transform = CGAffineTransformIdentity;
|
|
4390
3726
|
_nativeTabBarView.transform = CGAffineTransformIdentity;
|
|
4391
3727
|
_nativeSubHeaderView.transform = CGAffineTransformIdentity;
|
|
4392
|
-
[self updateTopScrollEdgeForScrollView:_observedScrollView];
|
|
4393
|
-
[self updateScrollEdgeContentMasks];
|
|
4394
3728
|
}
|
|
4395
3729
|
|
|
4396
3730
|
#pragma mark - Pager navigation
|
|
@@ -4402,7 +3736,7 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
4402
3736
|
|
|
4403
3737
|
- (void)goTo:(NSInteger)index animated:(BOOL)animated
|
|
4404
3738
|
{
|
|
4405
|
-
[self
|
|
3739
|
+
[self offsetDiag:@"go-to" page:index scroll:_observedScrollView];
|
|
4406
3740
|
if (_isBeingRecycled || index < 0 || index >= _pageControllers.count) return;
|
|
4407
3741
|
_hasReceivedPageCommand = YES;
|
|
4408
3742
|
_hasAppliedInitialPage = YES;
|
|
@@ -4533,7 +3867,6 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
4533
3867
|
if (!self->_transitioning && !self->_needsSlotRebuild) {
|
|
4534
3868
|
[self attachScrollObserverForCurrentPage];
|
|
4535
3869
|
}
|
|
4536
|
-
[self updateScrollEdgeContentMasks];
|
|
4537
3870
|
});
|
|
4538
3871
|
}
|
|
4539
3872
|
|
|
@@ -4585,6 +3918,7 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
4585
3918
|
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
|
|
4586
3919
|
{
|
|
4587
3920
|
[self updateHeaderSettledStateForceBusy:YES];
|
|
3921
|
+
[self offsetDiag:@"pager-drag-begin" page:_currentIndex scroll:_observedScrollView];
|
|
4588
3922
|
if (_nativeSmoothHeaderScrollEnabled && scrollView == _pagerScrollView) {
|
|
4589
3923
|
[_contentPressCancellationGesture cancelPressForPan:scrollView.panGestureRecognizer];
|
|
4590
3924
|
}
|
|
@@ -4741,7 +4075,6 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
4741
4075
|
CGFloat offset = progress - position;
|
|
4742
4076
|
position = MAX(0, MIN(position, (NSInteger)_pageControllers.count - 1));
|
|
4743
4077
|
[self updatePageStateTransitionProgress:progress];
|
|
4744
|
-
[self updateScrollEdgeContentMasks];
|
|
4745
4078
|
[_nativeTabBarView setProgress:progress];
|
|
4746
4079
|
const auto emitter = [self eventEmitter];
|
|
4747
4080
|
if (emitter) {
|
|
@@ -4760,7 +4093,6 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
4760
4093
|
tabProgress = _currentIndex + (_destinationIndex - _currentIndex) * transitionProgress;
|
|
4761
4094
|
}
|
|
4762
4095
|
[self updatePageStateTransitionProgress:tabProgress];
|
|
4763
|
-
[self updateScrollEdgeContentMasks];
|
|
4764
4096
|
[_nativeTabBarView setProgress:tabProgress];
|
|
4765
4097
|
const auto emitter = [self eventEmitter];
|
|
4766
4098
|
if (emitter) {
|
|
@@ -4778,6 +4110,7 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
4778
4110
|
|
|
4779
4111
|
- (void)emitPageSelected:(NSInteger)position
|
|
4780
4112
|
{
|
|
4113
|
+
[self offsetDiag:@"selection-complete" page:position scroll:_observedScrollView];
|
|
4781
4114
|
const auto emitter = [self eventEmitter];
|
|
4782
4115
|
if (emitter) emitter->onPageSelected({.position = (double)position});
|
|
4783
4116
|
}
|
|
@@ -4922,12 +4255,12 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
4922
4255
|
_currentLogicalOffset = logical;
|
|
4923
4256
|
_headerOffset = _pagerTopLogicalTarget;
|
|
4924
4257
|
[self applyHeaderOffset];
|
|
4258
|
+
[self offsetDiag:[NSString stringWithFormat:@"pager-top-complete-token=%lu-target=%.4f", (unsigned long)_pagerTopToken, _pagerTopLogicalTarget] page:_currentIndex scroll:scrollView];
|
|
4925
4259
|
[self cancelPagerTop];
|
|
4926
4260
|
}
|
|
4927
4261
|
|
|
4928
4262
|
- (void)scrollToTop:(NSInteger)target animated:(BOOL)animated
|
|
4929
4263
|
{
|
|
4930
|
-
[self cancelTopInsetReboundCheck];
|
|
4931
4264
|
UIScrollView *scrollView = _observedScrollView;
|
|
4932
4265
|
NSString *key = _observedPageKey;
|
|
4933
4266
|
if ((target != 0 && target != 1) || _isBeingRecycled || _transitioning || _isPagerDragging ||
|
|
@@ -4959,6 +4292,7 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
4959
4292
|
[self applyHeaderOffset];
|
|
4960
4293
|
CGFloat physicalTarget = RNCLimitRestoredScrollOffset(logicalTarget - scrollView.contentInset.top,
|
|
4961
4294
|
scrollView.contentSize.height, scrollView.bounds.size.height, scrollView.contentInset.top, scrollView.contentInset.bottom);
|
|
4295
|
+
[self offsetDiag:[NSString stringWithFormat:@"pager-top-begin-token=%lu-target=%ld-animated=%d", (unsigned long)_pagerTopToken, (long)target, animated] page:_currentIndex scroll:scrollView];
|
|
4962
4296
|
_dispatchingPagerTop = YES;
|
|
4963
4297
|
[scrollView setContentOffset:CGPointMake(scrollView.contentOffset.x, physicalTarget) animated:animated];
|
|
4964
4298
|
_dispatchingPagerTop = NO;
|
|
@@ -5023,22 +4357,6 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
5023
4357
|
: velocity;
|
|
5024
4358
|
BOOL hasMotion = MAX(fabs(intent.x), fabs(intent.y)) >= 1;
|
|
5025
4359
|
BOOL horizontal = hasMotion && fabs(intent.x) > fabs(intent.y);
|
|
5026
|
-
if (_sharedHeaderOuterPagerGesture.protectsNestedBody) {
|
|
5027
|
-
NSInteger pageCount = _pageControllers.count;
|
|
5028
|
-
BOOL validPage = _currentIndex >= 0 && _currentIndex < pageCount;
|
|
5029
|
-
NSInteger firstPageIndex = self.isLtrLayout ? 0 : pageCount - 1;
|
|
5030
|
-
NSInteger lastPageIndex = self.isLtrLayout ? pageCount - 1 : 0;
|
|
5031
|
-
BOOL outward = validPage &&
|
|
5032
|
-
((_currentIndex == firstPageIndex && intent.x > 0) ||
|
|
5033
|
-
(_currentIndex == lastPageIndex && intent.x < 0));
|
|
5034
|
-
UIScrollView *outer = RNCNestedOuterReactPagerScrollView(self);
|
|
5035
|
-
BOOL protectInnerPage = horizontal && validPage && pageCount > 1 &&
|
|
5036
|
-
_nestedScrollEnabled && _scrollEnabled && _pagerScrollView.scrollEnabled &&
|
|
5037
|
-
_pagerScrollView.panGestureRecognizer.enabled && outer != nil && outer.scrollEnabled &&
|
|
5038
|
-
[_sharedHeaderOuterPagerGesture.blockedPagerGestures
|
|
5039
|
-
containsObject:outer.panGestureRecognizer] && !outward;
|
|
5040
|
-
return protectInnerPage;
|
|
5041
|
-
}
|
|
5042
4360
|
RNCCollapsiblePagerLog([NSString stringWithFormat:
|
|
5043
4361
|
@"header-axis role=outer-pager-block dx=%.2f dy=%.2f velocity=(%.2f,%.2f) result=%d outer-pagers=%lu",
|
|
5044
4362
|
intent.x,
|
|
@@ -5078,21 +4396,24 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
5078
4396
|
return vertical;
|
|
5079
4397
|
}
|
|
5080
4398
|
if (gestureRecognizer != _blockerGesture) return YES;
|
|
5081
|
-
|
|
5082
|
-
|
|
5083
|
-
|
|
4399
|
+
if (!_nestedScrollEnabled) return NO;
|
|
4400
|
+
if (![gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) return NO;
|
|
4401
|
+
|
|
4402
|
+
UIPanGestureRecognizer *pan = (UIPanGestureRecognizer *)gestureRecognizer;
|
|
4403
|
+
CGPoint velocity = [pan velocityInView:self];
|
|
5084
4404
|
NSInteger pageCount = _pageControllers.count;
|
|
4405
|
+
if (pageCount == 0 || _currentIndex < 0 || _currentIndex >= pageCount) return NO;
|
|
4406
|
+
|
|
5085
4407
|
CGFloat absVelocityX = fabs(velocity.x);
|
|
5086
4408
|
CGFloat absVelocityY = fabs(velocity.y);
|
|
5087
|
-
|
|
5088
|
-
|
|
5089
|
-
BOOL
|
|
5090
|
-
|
|
5091
|
-
|
|
5092
|
-
|
|
5093
|
-
|
|
5094
|
-
|
|
5095
|
-
return shouldBegin;
|
|
4409
|
+
if (absVelocityX <= absVelocityY || absVelocityX < 1.0f) return NO;
|
|
4410
|
+
|
|
4411
|
+
BOOL isLtr = self.isLtrLayout;
|
|
4412
|
+
NSInteger firstPageIndex = isLtr ? 0 : pageCount - 1;
|
|
4413
|
+
NSInteger lastPageIndex = isLtr ? pageCount - 1 : 0;
|
|
4414
|
+
if (_currentIndex == firstPageIndex && velocity.x > 0) return YES;
|
|
4415
|
+
if (_currentIndex == lastPageIndex && velocity.x < 0) return YES;
|
|
4416
|
+
return NO;
|
|
5096
4417
|
}
|
|
5097
4418
|
|
|
5098
4419
|
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
|
|
@@ -5102,29 +4423,13 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
5102
4423
|
_sharedHeaderPressCancellationGestureHost == nil) return NO;
|
|
5103
4424
|
UIView *touchView = touch.view;
|
|
5104
4425
|
BOOL beginsInSharedHeader = touchView == _sharedHeaderHostView ||
|
|
5105
|
-
[touchView isDescendantOfView:_sharedHeaderHostView]
|
|
5106
|
-
|
|
5107
|
-
[touchView isDescendantOfView:_pinnedStickyHostView];
|
|
5108
|
-
if (_sharedHeaderOuterPagerGesture.trackedTouch != nil &&
|
|
5109
|
-
_sharedHeaderOuterPagerGesture.trackedTouch != touch) return NO;
|
|
5110
|
-
UIScrollView *outer = RNCNestedOuterReactPagerScrollView(self);
|
|
5111
|
-
BOOL beginsInNestedBody = !beginsInSharedHeader && _nestedScrollEnabled &&
|
|
5112
|
-
_scrollEnabled && _pagerScrollView.scrollEnabled &&
|
|
5113
|
-
_pagerScrollView.panGestureRecognizer.enabled && _pageControllers.count > 1 &&
|
|
5114
|
-
outer != nil && outer.scrollEnabled &&
|
|
5115
|
-
[_sharedHeaderOuterPagerGesture.blockedPagerGestures containsObject:outer.panGestureRecognizer] &&
|
|
5116
|
-
(touchView == _pagerScrollView || [touchView isDescendantOfView:_pagerScrollView]);
|
|
5117
|
-
if (!beginsInSharedHeader && !beginsInNestedBody) return NO;
|
|
5118
|
-
|
|
5119
|
-
_sharedHeaderOuterPagerGesture.trackedTouch = touch;
|
|
5120
|
-
_sharedHeaderOuterPagerGesture.protectsNestedBody = beginsInNestedBody;
|
|
5121
|
-
_sharedHeaderOuterPagerGesture.cancelsTouchesInView = !beginsInNestedBody;
|
|
4426
|
+
[touchView isDescendantOfView:_sharedHeaderHostView];
|
|
4427
|
+
if (!beginsInSharedHeader) return NO;
|
|
5122
4428
|
|
|
5123
4429
|
RNCCollapsiblePagerLog([NSString stringWithFormat:
|
|
5124
|
-
@"outer-pager-touch target=%@ outer-pagers=%lu
|
|
4430
|
+
@"outer-pager-touch target=%@ outer-pagers=%lu",
|
|
5125
4431
|
touchView == nil ? @"none" : NSStringFromClass(touchView.class),
|
|
5126
|
-
(unsigned long)_sharedHeaderOuterPagerGesture.blockedPagerGestures.count
|
|
5127
|
-
beginsInNestedBody]);
|
|
4432
|
+
(unsigned long)_sharedHeaderOuterPagerGesture.blockedPagerGestures.count]);
|
|
5128
4433
|
return YES;
|
|
5129
4434
|
}
|
|
5130
4435
|
if (gestureRecognizer == _contentPressCancellationGesture) {
|
|
@@ -5133,17 +4438,14 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
5133
4438
|
return _nativeSmoothHeaderScrollEnabled && !_isBeingRecycled &&
|
|
5134
4439
|
_contentPressCancellationGesture.view != nil &&
|
|
5135
4440
|
[touchView isDescendantOfView:_pagerScrollView] &&
|
|
5136
|
-
![touchView isDescendantOfView:_sharedHeaderHostView]
|
|
5137
|
-
![touchView isDescendantOfView:_pinnedStickyHostView];
|
|
4441
|
+
![touchView isDescendantOfView:_sharedHeaderHostView];
|
|
5138
4442
|
}
|
|
5139
4443
|
if (gestureRecognizer == _sharedHeaderPressCancellationGesture) {
|
|
5140
4444
|
if (!_nativeSmoothHeaderScrollEnabled || _isBeingRecycled ||
|
|
5141
4445
|
_sharedHeaderPressCancellationGestureHost == nil) return NO;
|
|
5142
4446
|
UIView *touchView = touch.view;
|
|
5143
4447
|
BOOL beginsInSharedHeader = touchView == _sharedHeaderHostView ||
|
|
5144
|
-
[touchView isDescendantOfView:_sharedHeaderHostView]
|
|
5145
|
-
touchView == _pinnedStickyHostView ||
|
|
5146
|
-
[touchView isDescendantOfView:_pinnedStickyHostView];
|
|
4448
|
+
[touchView isDescendantOfView:_sharedHeaderHostView];
|
|
5147
4449
|
if (!beginsInSharedHeader) return NO;
|
|
5148
4450
|
|
|
5149
4451
|
RNCCollapsiblePagerLog([NSString stringWithFormat:
|
|
@@ -5154,9 +4456,7 @@ static void RNCLogNativeTabScrollBoundary(NSString *owner,
|
|
|
5154
4456
|
if (gestureRecognizer == _verticalPagerGesture) {
|
|
5155
4457
|
UIView *touchView = touch.view;
|
|
5156
4458
|
return touchView != _sharedHeaderHostView &&
|
|
5157
|
-
![touchView isDescendantOfView:_sharedHeaderHostView]
|
|
5158
|
-
touchView != _pinnedStickyHostView &&
|
|
5159
|
-
![touchView isDescendantOfView:_pinnedStickyHostView];
|
|
4459
|
+
![touchView isDescendantOfView:_sharedHeaderHostView];
|
|
5160
4460
|
}
|
|
5161
4461
|
// A new touch can cancel UIKit's animation before its first frame. Queue a
|
|
5162
4462
|
// non-animated settle for the next safe transition boundary instead of
|