Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(paper): prevent freeze on layout update during transition #941

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions ios/RNCPagerView.h
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
#import <React/RCTView.h>
#import <React/RCTEventDispatcher.h>
#import <React/RCTShadowView.h>
#import <React/UIView+React.h>
#import <UIKit/UIKit.h>
#import "UIView+isHorizontalRtlLayout.h"

NS_ASSUME_NONNULL_BEGIN

@interface RNCPagerView: UIView <RtlLayoutProtocol>
@interface RNCPagerView: RCTView <RtlLayoutProtocol>

- (instancetype)initWithEventDispatcher:(id<RCTEventDispatcherProtocol> )eventDispatcher;
- (instancetype)initWithBridge:(RCTBridge *)bridge;

@property(nonatomic) NSInteger initialPage;
@property(nonatomic) NSInteger lastReportedIndex;
Expand All @@ -25,7 +25,7 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, copy) RCTDirectEventBlock onPageScrollStateChanged;
@property(nonatomic) BOOL overdrag;
@property(nonatomic) NSString* layoutDirection;
@property(nonatomic, assign) BOOL animating;
@property(nonatomic, assign) BOOL transitioning;

- (void)goTo:(NSInteger)index animated:(BOOL)animated;
- (void)shouldScroll:(BOOL)scrollEnabled;
Expand Down
24 changes: 15 additions & 9 deletions ios/RNCPagerView.m
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#import "RNCPagerView.h"
#import "React/RCTLog.h"
#import <React/RCTViewManager.h>
#import <React/RCTUIManager.h>

#import "UIViewController+CreateExtension.h"
#import "RCTOnPageScrollEvent.h"
Expand All @@ -13,7 +14,7 @@ @interface RNCPagerView () <UIPageViewControllerDataSource, UIPageViewController
@property(nonatomic, assign) UIPanGestureRecognizer* panGestureRecognizer;

@property(nonatomic, strong) UIPageViewController *reactPageViewController;
@property(nonatomic, strong) RCTEventDispatcher *eventDispatcher;
@property(nonatomic, strong) id<RCTEventDispatcherProtocol> eventDispatcher;

@property(nonatomic, weak) UIScrollView *scrollView;
@property(nonatomic, weak) UIView *currentView;
Expand All @@ -30,10 +31,12 @@ - (void)shouldDismissKeyboard:(NSString *)dismissKeyboard;

@implementation RNCPagerView {
uint16_t _coalescingKey;
__weak RCTBridge * _bridge;
}

- (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher {
- (instancetype)initWithBridge:(RCTBridge *)bridge {
if (self = [super init]) {
_bridge = bridge;
_scrollEnabled = YES;
_pageMargin = 0;
_lastReportedIndex = -1;
Expand All @@ -44,7 +47,7 @@ - (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher {
_dismissKeyboard = UIScrollViewKeyboardDismissModeNone;
#endif
_coalescingKey = 0;
_eventDispatcher = eventDispatcher;
_eventDispatcher = bridge.eventDispatcher;
_cachedControllers = [NSHashTable hashTableWithOptions:NSHashTableStrongMemory];
_overdrag = NO;
_layoutDirection = @"ltr";
Expand Down Expand Up @@ -178,7 +181,7 @@ - (void)setReactViewControllers:(NSInteger)index
uint16_t coalescingKey = _coalescingKey++;

if (animated == YES) {
self.animating = YES;
[self setTransitioning:YES];
}

[self.reactPageViewController setViewControllers:@[controller]
Expand All @@ -190,10 +193,8 @@ - (void)setReactViewControllers:(NSInteger)index
strongSelf.currentView = controller.view;

[strongSelf enableSwipe];

if (finished) {
strongSelf.animating = NO;
}

[strongSelf setTransitioning:NO];

if (strongSelf.eventDispatcher) {
if (strongSelf.lastReportedIndex != strongSelf.currentIndex) {
Expand Down Expand Up @@ -245,6 +246,11 @@ - (void)enableSwipe {
self.reactPageViewController.view.userInteractionEnabled = YES;
}

- (void)setTransitioning:(BOOL)transitioning {
_transitioning = transitioning;
[_bridge.uiManager setLocalData:@{@"transitioning": @(transitioning)} forView:self];
}

- (void)goTo:(NSInteger)index animated:(BOOL)animated {
NSInteger numberOfPages = self.reactSubviews.count;

Expand All @@ -267,7 +273,7 @@ - (void)goTo:(NSInteger)index animated:(BOOL)animated {

long diff = labs(index - _currentIndex);

[self goToViewController:index direction:direction animated:(!self.animating && animated) shouldCallOnPageSelected: YES];
[self goToViewController:index direction:direction animated:(!_transitioning && animated) shouldCallOnPageSelected: YES];

if (diff == 0) {
[self goToViewController:index direction:direction animated:NO shouldCallOnPageSelected:YES];
Expand Down
10 changes: 8 additions & 2 deletions ios/RNCPagerViewManager.m
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@

#import "RNCPagerViewManager.h"
#import "RNCPagerViewShadowView.h"
krozniata marked this conversation as resolved.
Show resolved Hide resolved

@implementation RNCPagerViewManager

Expand Down Expand Up @@ -30,7 +31,7 @@ - (void) goToPage
RCTLogError(@"Cannot find RNCPagerView with tag #%@", reactTag);
return;
}
if (!animated || !view.animating) {
if (!animated || !view.transitioning) {
[view goTo:index.integerValue animated:animated];
}
}];
Expand Down Expand Up @@ -80,7 +81,12 @@ - (void) changeScrollEnabled


- (UIView *)view {
return [[RNCPagerView alloc] initWithEventDispatcher:self.bridge.eventDispatcher];
return [[RNCPagerView alloc] initWithBridge: self.bridge];
}


- (RCTShadowView *)shadowView {
return [RNCPagerViewShadowView new];
}

@end
5 changes: 5 additions & 0 deletions ios/RNCPagerViewShadowView.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#import <React/RCTShadowView.h>

@interface RNCPagerViewShadowView : RCTShadowView

@end
22 changes: 22 additions & 0 deletions ios/RNCPagerViewShadowView.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#import "RNCPagerViewShadowView.h"

@implementation RNCPagerViewShadowView {
BOOL _transitioning;
}

- (void)layoutWithMetrics:(RCTLayoutMetrics)layoutMetrics
layoutContext:(RCTLayoutContext)layoutContext {
if (_transitioning) {
return;
}

[super layoutWithMetrics:layoutMetrics layoutContext:layoutContext];
}
krozniata marked this conversation as resolved.
Show resolved Hide resolved

- (void)setLocalData:(NSDictionary *)localData {
[super setLocalData:localData];

_transitioning = [localData[@"transitioning"] boolValue];
}

@end
Loading