@@ -176,24 +176,9 @@ - (void)updateProps:(const facebook::react::Props::Shared &)props oldProps:(cons
176176 [super updateProps: props oldProps: oldProps];
177177}
178178
179- - (void )handleCommand : (const NSString *)commandName args : (const NSArray *)args {
180- RCTRNCViewPagerHandleCommand (self, commandName, args);
181- }
182179
183180#pragma mark - Internal methods
184181
185- - (void )setPage : (NSInteger )index {
186- [self goTo: index animated: YES ];
187- }
188-
189- - (void )setPageWithoutAnimation : (NSInteger )index {
190- [self goTo: index animated: NO ];
191- }
192-
193- - (void )setScrollEnabledImperatively : (BOOL )scrollEnabled {
194- [scrollView setScrollEnabled: scrollEnabled];
195- }
196-
197182- (void )disableSwipe {
198183 self.nativePageViewController .view .userInteractionEnabled = NO ;
199184}
@@ -244,9 +229,9 @@ - (void)setPagerViewControllers:(NSInteger)index
244229 __strong RNCPagerViewComponentView *strongSelf = weakSelf;
245230 [strongSelf enableSwipe ];
246231 if (strongSelf->_eventEmitter != nullptr ) {
247- const auto strongEventEmitter = *std::dynamic_pointer_cast< const RNCViewPagerEventEmitter>( strongSelf-> _eventEmitter ) ;
232+ const auto eventEmitter = [ strongSelf pagerEventEmitter ] ;
248233 int position = (int ) index;
249- strongEventEmitter. onPageSelected (RNCViewPagerEventEmitter::OnPageSelected{.position = static_cast <double >(position)});
234+ eventEmitter-> onPageSelected (RNCViewPagerEventEmitter::OnPageSelected{.position = static_cast <double >(position)});
250235 strongSelf->_currentIndex = index;
251236 }
252237 [strongSelf updateLayoutMetrics: strongSelf->_layoutMetrics oldLayoutMetrics: strongSelf->_oldLayoutMetrics];
@@ -279,14 +264,14 @@ - (UIViewController *)currentlyDisplayed {
279264#pragma mark - UIScrollViewDelegate
280265
281266- (void )scrollViewWillBeginDragging : (UIScrollView *)scrollView {
282- const auto strongEventEmitter = *std::dynamic_pointer_cast< const RNCViewPagerEventEmitter>(_eventEmitter) ;
283- strongEventEmitter. onPageScrollStateChanged (RNCViewPagerEventEmitter::OnPageScrollStateChanged{.pageScrollState = RNCViewPagerEventEmitter::OnPageScrollStateChangedPageScrollState::Dragging });
267+ const auto eventEmitter = [ self pagerEventEmitter ] ;
268+ eventEmitter-> onPageScrollStateChanged (RNCViewPagerEventEmitter::OnPageScrollStateChanged{.pageScrollState = RNCViewPagerEventEmitter::OnPageScrollStateChangedPageScrollState::Dragging });
284269}
285270
286271- (void )scrollViewWillEndDragging : (UIScrollView *)scrollView withVelocity : (CGPoint)velocity targetContentOffset : (inout CGPoint *)targetContentOffset {
287272
288- const auto strongEventEmitter = *std::dynamic_pointer_cast< const RNCViewPagerEventEmitter>(_eventEmitter) ;
289- strongEventEmitter. onPageScrollStateChanged (RNCViewPagerEventEmitter::OnPageScrollStateChanged{.pageScrollState = RNCViewPagerEventEmitter::OnPageScrollStateChangedPageScrollState::Settling });
273+ const auto eventEmitter = [ self pagerEventEmitter ] ;
274+ eventEmitter-> onPageScrollStateChanged (RNCViewPagerEventEmitter::OnPageScrollStateChanged{.pageScrollState = RNCViewPagerEventEmitter::OnPageScrollStateChangedPageScrollState::Settling });
290275
291276 if (!_overdrag) {
292277 NSInteger maxIndex = _nativeChildrenViewControllers.count - 1 ;
@@ -299,44 +284,26 @@ - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoi
299284 CGPoint croppedOffset = [self isHorizontal ] ? CGPointMake (topBound, 0 ) : CGPointMake (0 , topBound);
300285 *targetContentOffset = croppedOffset;
301286
302- strongEventEmitter. onPageScrollStateChanged (RNCViewPagerEventEmitter::OnPageScrollStateChanged{.pageScrollState = RNCViewPagerEventEmitter::OnPageScrollStateChangedPageScrollState::Idle });
287+ eventEmitter-> onPageScrollStateChanged (RNCViewPagerEventEmitter::OnPageScrollStateChanged{.pageScrollState = RNCViewPagerEventEmitter::OnPageScrollStateChangedPageScrollState::Idle });
303288 }
304289 }
305-
306-
307290}
308291
309292- (void )scrollViewDidEndDecelerating : (UIScrollView *)scrollView {
310- const auto strongEventEmitter = *std::dynamic_pointer_cast<const RNCViewPagerEventEmitter>(_eventEmitter);
311- strongEventEmitter.onPageScrollStateChanged (RNCViewPagerEventEmitter::OnPageScrollStateChanged{.pageScrollState = RNCViewPagerEventEmitter::OnPageScrollStateChangedPageScrollState::Idle });
312- }
313-
314- - (BOOL )isHorizontalRtlLayout {
315- return self.isHorizontal && !self.isLtrLayout ;
316- }
317-
318- - (BOOL )isHorizontal {
319- return _nativePageViewController.navigationOrientation == UIPageViewControllerNavigationOrientationHorizontal;
293+ const auto eventEmitter = [self pagerEventEmitter ];
294+ eventEmitter->onPageScrollStateChanged (RNCViewPagerEventEmitter::OnPageScrollStateChanged{.pageScrollState = RNCViewPagerEventEmitter::OnPageScrollStateChangedPageScrollState::Idle });
320295}
321296
322- - (BOOL )isLtrLayout {
323- return [_layoutDirection isEqualToString: @" ltr" ];
324- }
325297
326298- (void )scrollViewDidScroll : (UIScrollView *)scrollView {
327- CGPoint point = scrollView.contentOffset ;
328-
329- float offset = 0 ;
330-
331- if (self.isHorizontal ) {
332- if (scrollView.frame .size .width != 0 ) {
333- offset = (point.x - scrollView.frame .size .width )/scrollView.frame .size .width ;
334- }
335- } else {
336- if (scrollView.frame .size .height != 0 ) {
337- offset = (point.y - scrollView.frame .size .height )/scrollView.frame .size .height ;
338- }
299+ CGFloat contentOffset = [self isHorizontal ] ? scrollView.contentOffset .x : scrollView.contentOffset .y ;
300+ CGFloat frameSize = [self isHorizontal ] ? scrollView.frame .size .width : scrollView.frame .size .height ;
301+
302+ if (frameSize == 0 ) {
303+ return ;
339304 }
305+
306+ float offset = (contentOffset - frameSize)/frameSize;
340307
341308 float absoluteOffset = fabs (offset);
342309
@@ -372,21 +339,10 @@ - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
372339 }
373340
374341 float interpolatedOffset = absoluteOffset * labs (_destinationIndex - _currentIndex);
375-
376- const auto strongEventEmitter = *std::dynamic_pointer_cast<const RNCViewPagerEventEmitter>(_eventEmitter);
377- int eventPosition = (int ) position;
378- strongEventEmitter.onPageScroll (RNCViewPagerEventEmitter::OnPageScroll{.position = static_cast <double >(eventPosition), .offset = interpolatedOffset});
379-
380- // This is temporary workaround to allow animations based on onPageScroll event
381- // until Fabric implements proper NativeAnimationDriver,
382- // see: https://github.com/facebook/react-native/blob/44f431b471c243c92284aa042d3807ba4d04af65/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm#L59
383- NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys: [[RCTOnPageScrollEvent alloc ] initWithReactTag: [NSNumber numberWithInt: self .tag] position: @(position) offset: @(interpolatedOffset)], @" event" , nil ];
384- [[NSNotificationCenter defaultCenter ] postNotificationName: @" RCTNotifyEventDispatcherObserversOfEvent_DEPRECATED"
385- object: nil
386- userInfo: userInfo];
342+
343+ [self sendScrollEventsForPosition: position offset: interpolatedOffset];
387344}
388345
389-
390346#pragma mark - UIPageViewControllerDelegate
391347
392348- (void )pageViewController : (UIPageViewController *)pageViewController
@@ -398,9 +354,9 @@ - (void)pageViewController:(UIPageViewController *)pageViewController
398354 NSUInteger currentIndex = [_nativeChildrenViewControllers indexOfObject: currentVC];
399355 _currentIndex = currentIndex;
400356 int position = (int ) currentIndex;
401- const auto strongEventEmitter = *std::dynamic_pointer_cast< const RNCViewPagerEventEmitter>(_eventEmitter) ;
402- strongEventEmitter. onPageSelected (RNCViewPagerEventEmitter::OnPageSelected{.position = static_cast <double >(position)});
403- strongEventEmitter. onPageScroll (RNCViewPagerEventEmitter::OnPageScroll{.position = static_cast <double >(position), .offset = 0.0 });
357+ const auto eventEmitter = [ self pagerEventEmitter ] ;
358+ eventEmitter-> onPageSelected (RNCViewPagerEventEmitter::OnPageSelected{.position = static_cast <double >(position)});
359+ eventEmitter-> onPageScroll (RNCViewPagerEventEmitter::OnPageScroll{.position = static_cast <double >(position), .offset = 0.0 });
404360 }
405361}
406362
@@ -419,6 +375,67 @@ - (UIViewController *)pageViewController:(UIPageViewController *)pageViewControl
419375 return [self nextControllerForController: viewController inDirection: direction];
420376}
421377
378+ #pragma mark - Imperative methods exposed to React Native
379+
380+ - (void )handleCommand : (const NSString *)commandName args : (const NSArray *)args {
381+ RCTRNCViewPagerHandleCommand (self, commandName, args);
382+ }
383+
384+ - (void )setPage : (NSInteger )index {
385+ [self goTo: index animated: YES ];
386+ }
387+
388+ - (void )setPageWithoutAnimation : (NSInteger )index {
389+ [self goTo: index animated: NO ];
390+ }
391+
392+ - (void )setScrollEnabledImperatively : (BOOL )scrollEnabled {
393+ [scrollView setScrollEnabled: scrollEnabled];
394+ }
395+
396+ #pragma mark - Helpers
397+
398+ - (BOOL )isHorizontalRtlLayout {
399+ return self.isHorizontal && !self.isLtrLayout ;
400+ }
401+
402+ - (BOOL )isHorizontal {
403+ return _nativePageViewController.navigationOrientation == UIPageViewControllerNavigationOrientationHorizontal;
404+ }
405+
406+ - (BOOL )isLtrLayout {
407+ return [_layoutDirection isEqualToString: @" ltr" ];
408+ }
409+
410+ - (std::shared_ptr<const RNCViewPagerEventEmitter>)pagerEventEmitter
411+ {
412+ if (!_eventEmitter) {
413+ return nullptr ;
414+ }
415+
416+ assert (std::dynamic_pointer_cast<const RNCViewPagerEventEmitter>(_eventEmitter));
417+ return std::static_pointer_cast<const RNCViewPagerEventEmitter>(_eventEmitter);
418+ }
419+
420+ - (void )sendScrollEventsForPosition : (NSInteger )position offset : (CGFloat)offset {
421+ const auto eventEmitter = [self pagerEventEmitter ];
422+ eventEmitter->onPageScroll (RNCViewPagerEventEmitter::OnPageScroll{
423+ .position = static_cast <double >(position),
424+ .offset = offset
425+ });
426+
427+ // This is temporary workaround to allow animations based on onPageScroll event
428+ // until Fabric implements proper NativeAnimationDriver,
429+ // see: https://github.com/facebook/react-native/blob/44f431b471c243c92284aa042d3807ba4d04af65/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm#L59
430+ RCTOnPageScrollEvent *event = [[RCTOnPageScrollEvent alloc ] initWithReactTag: @(self .tag)
431+ position: @(position)
432+ offset: @(offset)];
433+ NSDictionary *userInfo = @{@" event" : event};
434+ [[NSNotificationCenter defaultCenter ] postNotificationName: @" RCTNotifyEventDispatcherObserversOfEvent_DEPRECATED"
435+ object: nil
436+ userInfo: userInfo];
437+ }
438+
422439#pragma mark - RCTComponentViewProtocol
423440
424441+ (ComponentDescriptorProvider)componentDescriptorProvider
0 commit comments