Skip to content

Commit

Permalink
fix: apply logic from paper on Fabric
Browse files Browse the repository at this point in the history
  • Loading branch information
WoLewicki committed May 31, 2022
1 parent 00932e4 commit ba46394
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 38 deletions.
70 changes: 54 additions & 16 deletions ios/RNSScreen.mm
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ @interface RNSScreenView ()
@implementation RNSScreenView {
__weak RCTBridge *_bridge;
#ifdef RN_FABRIC_ENABLED
// we recreate the behavior of `reactSetFrame` on new architecture
facebook::react::LayoutMetrics _oldLayoutMetrics;
facebook::react::LayoutMetrics _newLayoutMetrics;
RCTSurfaceTouchHandler *_touchHandler;
facebook::react::RNSScreenShadowNode::ConcreteState::Shared _state;
#else
Expand Down Expand Up @@ -288,6 +291,7 @@ - (void)notifyWillAppear
std::dynamic_pointer_cast<const facebook::react::RNSScreenEventEmitter>(_eventEmitter)
->onWillAppear(facebook::react::RNSScreenEventEmitter::OnWillAppear{});
}
[self updateLayoutMetrics:_layoutMetrics oldLayoutMetrics:_oldLayoutMetrics];
#else
if (self.onWillAppear) {
self.onWillAppear(nil);
Expand Down Expand Up @@ -444,6 +448,11 @@ - (void)prepareForRecycle
// TODO: Make sure that there is no edge case when this should be uncommented
// _controller=nil;
_dismissed = NO;
// we don't reset the transform of view at the end of custom transitions,
// so in order not to add code to all transitions, we just reset it here.
// Maybe it would be better to do it in each animation since we could change other
// view props there too and they need to be reset due to view recycling.
self.transform = CGAffineTransformIdentity;
_state.reset();
}

Expand Down Expand Up @@ -518,6 +527,24 @@ - (void)updateState:(facebook::react::State::Shared const &)state
_state = std::static_pointer_cast<const facebook::react::RNSScreenShadowNode::ConcreteState>(state);
}

- (void)updateLayoutMetrics:(const facebook::react::LayoutMetrics &)layoutMetrics
oldLayoutMetrics:(const facebook::react::LayoutMetrics &)oldLayoutMetrics
{
_layoutMetrics = layoutMetrics;
_oldLayoutMetrics = oldLayoutMetrics;
UIViewController *parentVC = self.reactViewController.parentViewController;
if (parentVC != nil && ![parentVC isKindOfClass:[RNScreensNavigationController class]]) {
[super updateLayoutMetrics:layoutMetrics oldLayoutMetrics:oldLayoutMetrics];
}
// when screen is mounted under RNScreensNavigationController it's size is controller
// by the navigation controller itself. That is, it is set to fill space of
// the controller. In that case we ignore react layout system from managing
// the screen dimensions and we wait for the screen VC to update and then we
// pass the dimensions to ui view manager to take into account when laying out
// subviews
// Explanation taken from `reactSetFrame`, which is old arch equivalent of this code.
}

#pragma mark - Paper specific
#else

Expand Down Expand Up @@ -612,9 +639,7 @@ - (void)invalidate
@implementation RNSScreen {
__weak id _previousFirstResponder;
CGRect _lastViewFrame;
#ifdef RN_FABRIC_ENABLED
RNSScreenView *_initialView;
#else
UIView *_fakeView;
CADisplayLink *_animationTimer;
CGFloat _currentAlpha;
Expand All @@ -623,7 +648,6 @@ @implementation RNSScreen {
int _dismissCount;
BOOL _isSwiping;
BOOL _shouldNotify;
#endif
}

#pragma mark - Common
Expand All @@ -646,12 +670,12 @@ - (instancetype)initWithView:(UIView *)view
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if (!_isSwiping) {
#ifdef RN_FABRIC_ENABLED
[RNSScreenWindowTraits updateWindowTraits];
[_initialView notifyWillAppear];
#else
if (!_isSwiping) {
[((RNSScreenView *)self.view) notifyWillAppear];
#endif
if (self.transitionCoordinator.isInteractive) {
// we started dismissing with swipe gesture
_isSwiping = YES;
Expand All @@ -661,26 +685,28 @@ - (void)viewWillAppear:(BOOL)animated
// The _isSwiping is still true, but we don't want to notify then
_shouldNotify = NO;
}

#ifdef RN_FABRIC_ENABLED
#else
[self hideHeaderIfNecessary];

#endif
// as per documentation of these methods
_goingForward = [self isBeingPresented] || [self isMovingToParentViewController];

[RNSScreenWindowTraits updateWindowTraits];
if (_shouldNotify) {
_closing = NO;
#ifdef RN_FABRIC_ENABLED
#else
[self notifyTransitionProgress:0.0 closing:_closing goingForward:_goingForward];
[self setupProgressNotification];
}
#endif
}
}

- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
#ifdef RN_FABRIC_ENABLED
[_initialView notifyWillDisappear];
#else
if (!self.transitionCoordinator.isInteractive) {
// user might have long pressed ios 14 back button item,
Expand All @@ -694,10 +720,15 @@ - (void)viewWillDisappear:(BOOL)animated
} else {
_dismissCount = 1;
}
#endif

// same flow as in viewWillAppear
if (!_isSwiping) {
#ifdef RN_FABRIC_ENABLED
[_initialView notifyWillDisappear];
#else
[((RNSScreenView *)self.view) notifyWillDisappear];
#endif
if (self.transitionCoordinator.isInteractive) {
_isSwiping = YES;
}
Expand All @@ -710,35 +741,37 @@ - (void)viewWillDisappear:(BOOL)animated

if (_shouldNotify) {
_closing = YES;
#ifdef RN_FABRIC_ENABLED
#else
[self notifyTransitionProgress:0.0 closing:_closing goingForward:_goingForward];
[self setupProgressNotification];
}
#endif
}
}

- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
if (!_isSwiping || _shouldNotify) {

#ifdef RN_FABRIC_ENABLED
[_initialView notifyAppear];
[_initialView notifyAppear];
#else
if (!_isSwiping || _shouldNotify) {
// we are going forward or dismissing without swipe
// or successfully swiped back
[((RNSScreenView *)self.view) notifyAppear];
[self notifyTransitionProgress:1.0 closing:NO goingForward:_goingForward];
#endif
}

_isSwiping = NO;
_shouldNotify = YES;
#endif
}

- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
#ifdef RN_FABRIC_ENABLED
[_initialView notifyDisappear];
if (self.parentViewController == nil && self.presentingViewController == nil) {
// screen dismissed, send event
[_initialView notifyDismissedWithCount:1];
Expand All @@ -755,16 +788,21 @@ - (void)viewDidDisappear:(BOOL)animated
[((RNSScreenView *)self.view) notifyDismissedWithCount:_dismissCount];
}
}

#endif
// same flow as in viewDidAppear
if (!_isSwiping || _shouldNotify) {
#ifdef RN_FABRIC_ENABLED
[_initialView notifyDisappear];
#else
[((RNSScreenView *)self.view) notifyDisappear];
[self notifyTransitionProgress:1.0 closing:YES goingForward:_goingForward];
#endif
}

_isSwiping = NO;
_shouldNotify = YES;

#ifdef RN_FABRIC_ENABLED
#else
[self traverseForScrollView:self.view];
#endif
}
Expand Down
48 changes: 26 additions & 22 deletions ios/RNSScreenStack.mm
Original file line number Diff line number Diff line change
Expand Up @@ -725,6 +725,32 @@ - (void)handleSwipe:(UIPanGestureRecognizer *)gestureRecognizer
}
}
}

- (id<UIViewControllerInteractiveTransitioning>)navigationController:(UINavigationController *)navigationController
interactionControllerForAnimationController:
(id<UIViewControllerAnimatedTransitioning>)animationController
{
return _interactionController;
}

- (id<UIViewControllerInteractiveTransitioning>)interactionControllerForDismissal:
(id<UIViewControllerAnimatedTransitioning>)animator
{
return _interactionController;
}

- (void)navigationController:(UINavigationController *)navigationController
didShowViewController:(UIViewController *)viewController
animated:(BOOL)animated
{
#ifdef RN_FABRIC_ENABLED
#else
if (self.onFinishTransitioning) {
self.onFinishTransitioning(nil);
}
#endif
[RNSScreenWindowTraits updateWindowTraits];
}
#endif

- (void)markChildUpdated
Expand Down Expand Up @@ -921,16 +947,6 @@ - (void)prepareForRecycle
#else
#pragma mark - Paper specific

- (void)navigationController:(UINavigationController *)navigationController
didShowViewController:(UIViewController *)viewController
animated:(BOOL)animated
{
if (self.onFinishTransitioning) {
self.onFinishTransitioning(nil);
}
[RNSScreenWindowTraits updateWindowTraits];
}

- (void)invalidate
{
_invalidated = YES;
Expand All @@ -942,18 +958,6 @@ - (void)invalidate
[_controller removeFromParentViewController];
}

- (id<UIViewControllerInteractiveTransitioning>)navigationController:(UINavigationController *)navigationController
interactionControllerForAnimationController:
(id<UIViewControllerAnimatedTransitioning>)animationController
{
return _interactionController;
}

- (id<UIViewControllerInteractiveTransitioning>)interactionControllerForDismissal:
(id<UIViewControllerAnimatedTransitioning>)animator
{
return _interactionController;
}
#endif // RN_FABRIC_ENABLED

@end
Expand Down

0 comments on commit ba46394

Please sign in to comment.