Skip to content

Commit c83e5c8

Browse files
authored
fix(ios): Fix vertical list scroll directionin rtl (#885)
* fix(ios): Fix vertical list scroll direction in rtl * chore(ios): Extract horizontal rtl utils to common protocol
1 parent e1a677b commit c83e5c8

6 files changed

+46
-15
lines changed

ios/LEGACY/Fabric/LEGACY_RNCPagerViewComponentView.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@
44
#import <Foundation/Foundation.h>
55
#import <React/RCTViewComponentView.h>
66
#import "UIViewController+CreateExtension.h"
7+
#import "UIView+isHorizontalRtlLayout.h"
78

89
NS_ASSUME_NONNULL_BEGIN
910

10-
@interface LEGACY_RNCPagerViewComponentView : RCTViewComponentView <UIPageViewControllerDataSource, UIPageViewControllerDelegate, UIScrollViewDelegate>
11+
@interface LEGACY_RNCPagerViewComponentView : RCTViewComponentView <UIPageViewControllerDataSource, UIPageViewControllerDelegate, UIScrollViewDelegate, isHorizontalRtlLayout>
1112

1213
@property(strong, nonatomic, readonly) UIPageViewController *nativePageViewController;
1314
@property(nonatomic, strong) NSMutableArray<UIViewController *> *nativeChildrenViewControllers;

ios/LEGACY/Fabric/LEGACY_RNCPagerViewComponentView.mm

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,7 @@ - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
328328

329329
NSInteger position = self.currentIndex;
330330

331+
BOOL isHorizontalRtl = [self isHorizontalRtlLayout];
331332
BOOL isAnimatingBackwards = offset<0;
332333

333334
if (scrollView.isDragging) {
@@ -341,8 +342,8 @@ - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
341342

342343
if (!_overdrag) {
343344
NSInteger maxIndex = _nativeChildrenViewControllers.count - 1;
344-
NSInteger firstPageIndex = [self isLtrLayout] ? 0 : maxIndex;
345-
NSInteger lastPageIndex = [self isLtrLayout] ? maxIndex : 0;
345+
NSInteger firstPageIndex = !isHorizontalRtl ? 0 : maxIndex;
346+
NSInteger lastPageIndex = !isHorizontalRtl ? maxIndex : 0;
346347
BOOL isFirstPage = _currentIndex == firstPageIndex;
347348
BOOL isLastPage = _currentIndex == lastPageIndex;
348349
CGFloat contentOffset =[self isHorizontal] ? scrollView.contentOffset.x : scrollView.contentOffset.y;

ios/LEGACY/LEGACY_RNCPagerView.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22
#import <React/RCTShadowView.h>
33
#import <React/UIView+React.h>
44
#import <UIKit/UIKit.h>
5+
#import "UIView+isHorizontalRtlLayout.h"
56

67
NS_ASSUME_NONNULL_BEGIN
78

8-
@interface LEGACY_RNCPagerView: UIView
9+
@interface LEGACY_RNCPagerView: UIView <RtlLayoutProtocol>
910

1011
- (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher;
1112

ios/LEGACY/LEGACY_RNCPagerView.m

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -260,11 +260,9 @@ - (void)goTo:(NSInteger)index animated:(BOOL)animated {
260260
return;
261261
}
262262

263-
BOOL isRTL = ![self isLtrLayout];
264-
265-
BOOL isForward = (index > self.currentIndex && !isRTL) || (index < self.currentIndex && isRTL);
263+
BOOL isHorizontalRtl = [self isHorizontalRtlLayout];
264+
BOOL isForward = isHorizontalRtl ? index < self.currentIndex : index > self.currentIndex;
266265

267-
268266
UIPageViewControllerNavigationDirection direction = isForward ? UIPageViewControllerNavigationDirectionForward : UIPageViewControllerNavigationDirectionReverse;
269267

270268
long diff = labs(index - _currentIndex);
@@ -353,13 +351,13 @@ - (void)pageViewController:(UIPageViewController *)pageViewController
353351

354352
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController
355353
viewControllerAfterViewController:(UIViewController *)viewController {
356-
UIPageViewControllerNavigationDirection direction = [self isLtrLayout] ? UIPageViewControllerNavigationDirectionForward : UIPageViewControllerNavigationDirectionReverse;
354+
UIPageViewControllerNavigationDirection direction = ![self isHorizontalRtlLayout] ? UIPageViewControllerNavigationDirectionForward : UIPageViewControllerNavigationDirectionReverse;
357355
return [self nextControllerForController:viewController inDirection:direction];
358356
}
359357

360358
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController
361359
viewControllerBeforeViewController:(UIViewController *)viewController {
362-
UIPageViewControllerNavigationDirection direction = [self isLtrLayout] ? UIPageViewControllerNavigationDirectionReverse : UIPageViewControllerNavigationDirectionForward;
360+
UIPageViewControllerNavigationDirection direction = ![self isHorizontalRtlLayout] ? UIPageViewControllerNavigationDirectionReverse : UIPageViewControllerNavigationDirectionForward;
363361
return [self nextControllerForController:viewController inDirection:direction];
364362
}
365363

@@ -382,8 +380,8 @@ - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoi
382380

383381
if (!_overdrag) {
384382
NSInteger maxIndex = self.reactSubviews.count - 1;
385-
BOOL isFirstPage = [self isLtrLayout] ? _currentIndex == 0 : _currentIndex == maxIndex;
386-
BOOL isLastPage = [self isLtrLayout] ? _currentIndex == maxIndex : _currentIndex == 0;
383+
BOOL isFirstPage = ![self isHorizontalRtlLayout] ? _currentIndex == 0 : _currentIndex == maxIndex;
384+
BOOL isLastPage = ![self isHorizontalRtlLayout] ? _currentIndex == maxIndex : _currentIndex == 0;
387385
CGFloat contentOffset =[self isHorizontal] ? scrollView.contentOffset.x : scrollView.contentOffset.y;
388386
CGFloat topBound = [self isHorizontal] ? scrollView.bounds.size.width : scrollView.bounds.size.height;
389387

@@ -423,7 +421,8 @@ - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
423421

424422
NSInteger position = self.currentIndex;
425423

426-
BOOL isAnimatingBackwards = ([self isLtrLayout] && offset<0) || (![self isLtrLayout] && offset > 0.05f);
424+
BOOL isHorizontalRtl = [self isHorizontalRtlLayout];
425+
BOOL isAnimatingBackwards = isHorizontalRtl ? offset > 0.05f : offset < 0;
427426

428427
if (scrollView.isDragging) {
429428
_destinationIndex = isAnimatingBackwards ? _currentIndex - 1 : _currentIndex + 1;
@@ -436,8 +435,8 @@ - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
436435

437436
if (!_overdrag) {
438437
NSInteger maxIndex = self.reactSubviews.count - 1;
439-
NSInteger firstPageIndex = [self isLtrLayout] ? 0 : maxIndex;
440-
NSInteger lastPageIndex = [self isLtrLayout] ? maxIndex : 0;
438+
NSInteger firstPageIndex = !isHorizontalRtl ? 0 : maxIndex;
439+
NSInteger lastPageIndex = !isHorizontalRtl ? maxIndex : 0;
441440
BOOL isFirstPage = _currentIndex == firstPageIndex;
442441
BOOL isLastPage = _currentIndex == lastPageIndex;
443442
CGFloat contentOffset =[self isHorizontal] ? scrollView.contentOffset.x : scrollView.contentOffset.y;
@@ -500,4 +499,5 @@ - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecogni
500499
- (BOOL)isLtrLayout {
501500
return [_layoutDirection isEqualToString:@"ltr"];
502501
}
502+
503503
@end

ios/UIView+isHorizontalRtlLayout.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#import <UIKit/UIKit.h>
2+
3+
@protocol RtlLayoutProtocol <NSObject>
4+
5+
@property (nonatomic, readonly) BOOL isHorizontal;
6+
@property (nonatomic, readonly) BOOL isLtrLayout;
7+
8+
@end
9+
10+
@interface UIView (RtlLayoutProtocol)
11+
12+
- (BOOL)isHorizontalRtlLayout;
13+
14+
@end

ios/UIView+isHorizontalRtlLayout.m

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#import "UIView+isHorizontalRtlLayout.h"
2+
3+
4+
@implementation UIView (RtlLayoutProtocol)
5+
6+
- (BOOL)isHorizontalRtlLayout {
7+
if ([self conformsToProtocol:@protocol(RtlLayoutProtocol)]) {
8+
id<RtlLayoutProtocol> layoutObject = (id<RtlLayoutProtocol>)self;
9+
return layoutObject.isHorizontal && !layoutObject.isLtrLayout;
10+
}
11+
return NO;
12+
}
13+
14+
@end

0 commit comments

Comments
 (0)