Skip to content

Commit 6ad35ce

Browse files
committed
feat: improve scroll delegate
1 parent 766e578 commit 6ad35ce

File tree

3 files changed

+31
-46
lines changed

3 files changed

+31
-46
lines changed

ios/PagerScrollDelegate.swift

Lines changed: 13 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,21 @@ import UIKit
44
Scroll delegate used to control underlying TabView's collection view.
55
*/
66
class PagerScrollDelegate: NSObject, UIScrollViewDelegate, UICollectionViewDelegate {
7-
// Store the original delegate to forward calls
87
weak var originalDelegate: UICollectionViewDelegate?
98
weak var delegate: PagerViewProviderDelegate?
109
var orientation: UICollectionView.ScrollDirection = .horizontal
1110

11+
private let handledSelectors: Set<Selector> = [
12+
#selector(scrollViewDidScroll(_:)),
13+
#selector(scrollViewWillBeginDragging(_:)),
14+
#selector(scrollViewWillBeginDecelerating(_:)),
15+
#selector(scrollViewDidEndDecelerating(_:)),
16+
#selector(scrollViewDidEndScrollingAnimation(_:)),
17+
#selector(scrollViewDidEndDragging(_:willDecelerate:)),
18+
#selector(collectionView(_:didEndDisplaying:forItemAt:)),
19+
#selector(collectionView(_:willDisplay:forItemAt:))
20+
]
21+
1222
func scrollViewDidScroll(_ scrollView: UIScrollView) {
1323
let isHorizontal = orientation == .horizontal
1424
let pageSize = isHorizontal ? scrollView.frame.width : scrollView.frame.height
@@ -60,39 +70,11 @@ class PagerScrollDelegate: NSObject, UIScrollViewDelegate, UICollectionViewDeleg
6070
}
6171

6272
override func responds(to aSelector: Selector!) -> Bool {
63-
let handledSelectors: [Selector] = [
64-
#selector(scrollViewDidScroll(_:)),
65-
#selector(scrollViewWillBeginDragging(_:)),
66-
#selector(scrollViewWillBeginDecelerating(_:)),
67-
#selector(scrollViewDidEndDecelerating(_:)),
68-
#selector(scrollViewDidEndScrollingAnimation(_:)),
69-
#selector(scrollViewDidEndDragging(_:willDecelerate:)),
70-
#selector(collectionView(_:didEndDisplaying:forItemAt:)),
71-
#selector(collectionView(_:willDisplay:forItemAt:))
72-
]
73-
74-
if handledSelectors.contains(aSelector) {
75-
return true
76-
}
77-
return originalDelegate?.responds(to: aSelector) ?? false
73+
handledSelectors.contains(aSelector) || (originalDelegate?.responds(to: aSelector) ?? false)
7874
}
7975

8076
override func forwardingTarget(for aSelector: Selector!) -> Any? {
81-
let handledSelectors: [Selector] = [
82-
#selector(scrollViewDidScroll(_:)),
83-
#selector(scrollViewWillBeginDragging(_:)),
84-
#selector(scrollViewWillBeginDecelerating(_:)),
85-
#selector(scrollViewDidEndDecelerating(_:)),
86-
#selector(scrollViewDidEndScrollingAnimation(_:)),
87-
#selector(scrollViewDidEndDragging(_:willDecelerate:)),
88-
#selector(collectionView(_:didEndDisplaying:forItemAt:)),
89-
#selector(collectionView(_:willDisplay:forItemAt:))
90-
]
91-
92-
if handledSelectors.contains(aSelector) {
93-
return nil
94-
}
95-
return originalDelegate
77+
handledSelectors.contains(aSelector) ? nil : originalDelegate
9678
}
9779
}
9880

ios/PagerViewProvider.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,9 @@ import UIKit
112112
parentViewController.addChild(hostingController)
113113
hostingController.view.backgroundColor = .clear
114114
addSubview(hostingController.view)
115-
hostingController.view.frame = bounds
115+
116+
hostingController.view.translatesAutoresizingMaskIntoConstraints = false
117+
hostingController.view.pinEdges(to: self)
116118

117119
hostingController.didMove(toParent: parentViewController)
118120
}

ios/RNCPagerViewComponentView.mm

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ - (instancetype)initWithFrame:(CGRect)frame
4040
_pagerViewProvider = [[PagerViewProvider alloc] initWithDelegate:self];
4141
self.contentView = _pagerViewProvider;
4242
}
43-
43+
4444
return self;
4545
}
4646

@@ -64,34 +64,34 @@ + (BOOL)shouldBeRecycled
6464
- (void)updateProps:(const facebook::react::Props::Shared &)props oldProps:(const facebook::react::Props::Shared &)oldProps{
6565
const auto &oldScreenProps = *std::static_pointer_cast<const RNCViewPagerProps>(_props);
6666
const auto &newScreenProps = *std::static_pointer_cast<const RNCViewPagerProps>(props);
67-
67+
6868
if (_pagerViewProvider.currentPage == -1) {
6969
_pagerViewProvider.currentPage = newScreenProps.initialPage;
7070
}
7171

7272
if (oldScreenProps.scrollEnabled != newScreenProps.scrollEnabled) {
7373
_pagerViewProvider.scrollEnabled = newScreenProps.scrollEnabled;
7474
}
75-
75+
7676
if (oldScreenProps.overdrag != newScreenProps.overdrag) {
7777
_pagerViewProvider.overdrag = newScreenProps.overdrag;
7878
}
79-
79+
8080
if (oldScreenProps.keyboardDismissMode != newScreenProps.keyboardDismissMode) {
8181
switch (newScreenProps.keyboardDismissMode) {
8282
case RNCViewPagerKeyboardDismissMode::None:
8383
_pagerViewProvider.keyboardDismissMode = UIScrollViewKeyboardDismissModeNone;
8484
break;
85-
85+
8686
case RNCViewPagerKeyboardDismissMode::OnDrag:
8787
_pagerViewProvider.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;
8888
}
8989
}
90-
90+
9191
if (oldScreenProps.orientation != newScreenProps.orientation) {
9292
_pagerViewProvider.orientation = newScreenProps.orientation == RNCViewPagerOrientation::Vertical ? UICollectionViewScrollDirectionVertical : UICollectionViewScrollDirectionHorizontal;
9393
}
94-
94+
9595
if (oldScreenProps.layoutDirection != newScreenProps.layoutDirection) {
9696
_pagerViewProvider.layoutDirection = newScreenProps.layoutDirection == RNCViewPagerLayoutDirection::Rtl ? PagerLayoutDirectionRtl : PagerLayoutDirectionLtr;
9797
}
@@ -113,23 +113,23 @@ - (void)onPageSelectedWithPosition:(NSInteger)position {
113113

114114
- (void)onPageScrollStateChangedWithState:(enum PageScrollState)state {
115115
const auto eventEmitter = [self pagerEventEmitter];
116-
116+
117117
RNCViewPagerEventEmitter::OnPageScrollStateChangedPageScrollState scrollState;
118-
118+
119119
switch (state) {
120120
case PageScrollStateIdle:
121121
scrollState = RNCViewPagerEventEmitter::OnPageScrollStateChangedPageScrollState::Idle;
122122
break;
123-
123+
124124
case PageScrollStateDragging:
125125
scrollState = RNCViewPagerEventEmitter::OnPageScrollStateChangedPageScrollState::Dragging;
126126
break;
127-
127+
128128
case PageScrollStateSettling:
129129
scrollState = RNCViewPagerEventEmitter::OnPageScrollStateChangedPageScrollState::Settling;
130130
break;
131131
}
132-
132+
133133
eventEmitter->onPageScrollStateChanged(RNCViewPagerEventEmitter::OnPageScrollStateChanged{
134134
.pageScrollState = scrollState
135135
});
@@ -156,14 +156,15 @@ - (void)setPageWithoutAnimation:(NSInteger)index {
156156
}
157157

158158
- (void)setScrollEnabledImperatively:(BOOL)scrollEnabled {
159+
_pagerViewProvider.scrollEnabled = scrollEnabled;
159160
}
160161

161162
- (std::shared_ptr<const RNCViewPagerEventEmitter>)pagerEventEmitter
162163
{
163164
if (!_eventEmitter) {
164165
return nullptr;
165166
}
166-
167+
167168
assert(std::dynamic_pointer_cast<const RNCViewPagerEventEmitter>(_eventEmitter));
168169
return std::static_pointer_cast<const RNCViewPagerEventEmitter>(_eventEmitter);
169170
}
@@ -174,7 +175,7 @@ - (void)sendScrollEventsForPosition:(NSInteger)position offset:(CGFloat)offset {
174175
.position = static_cast<double>(position),
175176
.offset = offset
176177
});
177-
178+
178179
// This is temporary workaround to allow animations based on onPageScroll event
179180
// until Fabric implements proper NativeAnimationDriver,
180181
// see: https://github.com/facebook/react-native/blob/44f431b471c243c92284aa042d3807ba4d04af65/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm#L59

0 commit comments

Comments
 (0)