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

feat: back gesture with full screen swipe #705

Merged

Conversation

intergalacticspacehighway
Copy link
Contributor

Previous PR - #665

Summary

Test Plan

  • Add fullScreenGestureEnabled on react navigation's native stack and try to swipe when the first page is reached in pager view.
  • Test fabricexample too with the same changes.
Screen.Recording.2022-12-03.at.4.51.52.PM.mov

Test with RTL enabled

I18nManager.forceRTL(true);

Screen.Recording.2022-12-03.at.4.48.26.PM.mov

What's required for testing (prerequisites)?

  • Run yarn install and pod install in example to upgrade the react navigation dependencies.
  • Add fullScreenGestureEnabled in react navigation screen options

What are the steps to reproduce (after prerequisites)?

  • Open any pager view example and swipe to go back with fullScreenGestureEnabled should work on the first page.

Compatibility

OS Implemented
iOS
Android

Checklist

  • I have tested this on a device and a simulator
  • I added the documentation in README.md
  • I updated the typed files (TS and Flow)

"@react-navigation/native": "^5.8.10",
"@react-navigation/native-stack": "5.0.4",
"@react-navigation/stack": "^5.12.8",
"@react-navigation/native": "~6.1.6",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Upgrade is required as fullScreenGestureEnabled requires new RNScreen version. Looks like it shouldn't break anything. https://reactnavigation.org/docs/upgrading-from-5.x/

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {

// Recognize simultaneously only if the other gesture is RN Screen's pan gesture (one that is used to perform fullScreenGestureEnabled)
if (gestureRecognizer == self.panGestureRecognizer && [NSStringFromClass([otherGestureRecognizer class]) isEqual: @"RNSPanGestureRecognizer"]) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RNSPanGestureRecognizer is the name of the pan gesture used by react-native-screens. This check is added to minimize the side effect of this change, as discussed here

@andreialecu
Copy link
Collaborator

andreialecu commented Mar 24, 2023

Awesome, thanks for this!

One quick question though - does this only apply to the first page?

If the user drags from the very left edge while on pane 2 of the pager, will he be allowed to go back in React Navigation on iOS?

CleanShot.2023-03-24.at.12.02.35.mp4

Here's what I mean, above. Right now we're doing this via a negative hitSlop as per this comment: PedroBern/react-native-collapsible-tab-view#248 (comment)

However it doesn't seem to always work, and has the side effect of nothing being able to be clicked within that edge - which is not necessarily a real issue, but seems like a hack nonetheless.

@intergalacticspacehighway
Copy link
Contributor Author

intergalacticspacehighway commented Mar 24, 2023

from the very left edge while on pane 2 of the pager

Yes, it should work. It at least works in the example app. It needs native stack navigator though.

Screen.Recording.2023-03-24.at.4.02.23.PM.mov

btw I noticed the scroll view based rewrite on next branch. So would need a different approach to make it work in that version. I can look when I get some time 😅

@intergalacticspacehighway
Copy link
Contributor Author

intergalacticspacehighway commented Mar 24, 2023

@andreialecu are you using native stack? if yes, I can look into it if you can share a minimal repro. JS based Stack navigator doesn't work with the edge back gesture and needs the hitSlop workaround like you mentioned.

@andreialecu
Copy link
Collaborator

Ah, not on the native stack yet because we still rely on https://github.com/IjzerenHein/react-native-shared-element which doesn't work with the native stack.

Once the shared element transitions in Reanimated mature, we should be able to move to the native stack finally. They're currently still incomplete and buggy.

Thanks for clarifying!

@troZee
Copy link
Member

troZee commented Mar 24, 2023

@intergalacticspacehighway @andreialecu
Thank you for sharing your thoughts here. I have tested this PR and it works 🎉

btw I noticed the scroll view based rewrite on next branch.

will create another ticket for that to have visibility on it.

@troZee troZee merged commit 769a3a2 into callstack:master Mar 24, 2023
@intergalacticspacehighway intergalacticspacehighway deleted the fix/full-swipe-back-gesture branch March 24, 2023 11:48
@troZee
Copy link
Member

troZee commented Mar 24, 2023

@ouabing
Copy link

ouabing commented Mar 25, 2023

I used to encounter an issue after applying this patch in the previous PR with react-native-screens enabled.

After I navigate from the screen with PagerView to another screen and go back, I cannot use back gesture anymore. self.panGestureRecognizer is changed and shouldRecognizeSimultaneouslyWithGestureRecognizer seems to not correctly recognize the latest self.panGestureRecognizer.

My observation is didMoveToWindow get called everytime I reenter the screen with PagerView if react-native-screens is enabled, and this line always assigns a new UIPanGestureRecognizer without remove the previous one.

My personal patch based on this PR is like below:

if (self.panGestureRecognizer) {
    [self removeGestureRecognizer:self.panGestureRecognizer];
}
UIPanGestureRecognizer* panGestureRecognizer = [UIPanGestureRecognizer new];
self.panGestureRecognizer = panGestureRecognizer;
panGestureRecognizer.delegate = self;
[self addGestureRecognizer: panGestureRecognizer];

Because I'm not sure if it's a common issue, so I just post here if someone need this.

@intergalacticspacehighway
Copy link
Contributor Author

@ouabing i moved the gesture initialiser from didMoveToWindow to initWithEventDispatcher in this PR. So, it should only get called once during the View creation. Can you try the version 6.2.0 and let us know if the issue persists? Thanks!

@ouabing
Copy link

ouabing commented Mar 25, 2023

@intergalacticspacehighway oh my apology for not checking the PR carefully. I'll try now, thanks for the work!

@ouabing
Copy link

ouabing commented Mar 25, 2023

Hi I just tested this PR and now I think my problem should be a new issue. I used to use this PR to solve another issue with react-native-tab-view(which uses react-native-pager-view), when a tab view is inside a pushed screen(not RNScreen's native stack but with RNScreen enabled in react-navigation), the back gesture won't work.

I noticed in the new PR the otherGestureRecognizer check is limited to the one RNScreen's native stack use, so the PR is not working any more in my case.

I will try to reproduce my case and create another issue maybe, thank you anyway!

@boboxiaodd
Copy link

@troZee i use react-native-pager-view for video show like TikTok
upgrade to 6.2.0 , gestureEnabled can't work for iOS ,i has to downgrade to 6.1.4

@intergalacticspacehighway
Copy link
Contributor Author

intergalacticspacehighway commented Apr 3, 2023

@boboxiaodd what do you mean gestureEnabled can't work for iOS? Can you explain in more detail or with a video?

There is no prop named gestureEnabled in the library. or do you mean scrollEnabled?

@boboxiaodd
Copy link

@tiagotwistag
Copy link

Hi I just tested this PR and now I think my problem should be a new issue. I used to use this PR to solve another issue with react-native-tab-view(which uses react-native-pager-view), when a tab view is inside a pushed screen(not RNScreen's native stack but with RNScreen enabled in react-navigation), the back gesture won't work.

I noticed in the new PR the otherGestureRecognizer check is limited to the one RNScreen's native stack use, so the PR is not working any more in my case.

I will try to reproduce my case and create another issue maybe, thank you anyway!

I believe I'm also facing the same issue, Is there any plan to support @react-navigation/stack?

td-tomasz added a commit to Transmission-Dynamics/react-native-pager-view that referenced this pull request Sep 13, 2023
@troZee
Copy link
Member

troZee commented Sep 25, 2023

Since the fact, this feat does not work, I am reverting it here: #771

troZee pushed a commit that referenced this pull request Dec 21, 2023
…mplementation (#783)

* wip: unsuspicious changes

* wip: unsuspicious changes v2

* FABRIC NEW IMPL -> OLD IMPL

* wip: bring back useLegacy on the RN side

* wip: bring back duplicate types to fix codegen issues

* wip: remove #705 related code for now

* wip: old/new impl division first draft

* wip: old/new impl division continued

* wip: old/new impl v3

* wip: add a `LEGACY_` prefix to all legacy implementation-related symbols

* wip: fix styles for new implementation on Fabric

* wip: move old/new impl into separate folders

* wip: fix old impl fabric symbol names

* wip: xcode changes

* wip: clean up & unify the naming convention

* wip: fix linter issues

* wip: fix styles for new implementation on Paper

* wip: make Fabric example run on another port by default to make it possible to run both examples in parallel

* wip: implement an abstraction over native commands invocations to reduce branching

* refactor: remove the unnecessary value for boolean props

* fix: bump react-native-safe-area-context to a Fabric-enabled version

* feat: bring back & adjust the `bootstrap-fabric` script

* feat: adjust the home screen title depending on the used architecture

* chore: update example/Podfile.lock

* chore: update an Xcode project file after building

* ci: make next branch events trigger ios/android build workflows

* chore: remove commented-out code related to #705 for now

* chore: add legacy implementation explanation comment

* wip: Android fixes

* fix: unnecessary comma in MainActivity.java

* feat: readme makeover

* chore: bump react-native-screens & react-native-gesture-handler in example

* refactor(android): extract module name to shared variable, add comment for context

* chore: remove unnecessary yarn.lock deps

* chore(ios): bring back removed build flags

* chore(ios): remove unnecessary concurrentRootEnabled method

According to React Native Upgrade Helper, this method is to be removed when updating to RN 0.72:
https://react-native-community.github.io/upgrade-helper/?from=0.71.14&to=0.72.0#RnDiffApp-ios-RnDiffApp-AppDelegate.mm

* fix(android): adjust incorrect param type on Fabric

* chore: remove unnecessary tsconfig.json comment

* chore(ios): bring back (currently unused) code related to #712 and #705
troZee added a commit that referenced this pull request Mar 31, 2024
* feat(iOS): change Fabric implementation to UIScrollView (#672)

* feat(iOS): change Fabric implementation to UIScrollView

* fix: fix offset values in vertical orientation

* feat: add initialPage props support

* feat: add RTL language support

* feat: add pageMargin prop support

* fix: fix typescript error

* feat: remove React.cloneElement

* feat(ios): add getPageOffset method

* fix: fix styles in old example

* fix: behavior on page remove

* chore: add GH actions (#680)

Co-authored-by: Piotr Trocki <[email protected]>

* feat(iOS): rewrite old arch to use UIScrollView (#681)

* feat: rewrite old arch to use UIScrollView

* feat: update example styles

* fix: sending event on scrollViewDidEndDecelerating

* feat: properly calculate width using orientation

* fix: change way of disabing scroll

* feat: rename to RNCPagerView

* fix: removing last page

* fix: remove unused properties, set animated

* chore: update release script

* Release 7.0.0-rc.0

* wip

* wip

* fabric example

* nit: comment

* make init consistent

* fix: multiple updates of frame and contentSize

* feat: add button to quickly switch layout direction

* sync with master (#756)

Co-authored-by: Piotr Trocki <[email protected]>

* chore: upgrade RN (paper example)

* chore: upgrade rn & fix issues (fabric example)

* chore: bump versions in package.json

* chore: fix eslint issue

* chore: exclude example from tsc

* feat(next): remove fabric example

* chore: update README

* fix broken overdrag on notch (#787)

Co-authored-by: Kuba Juszczyk <[email protected]>

* feat(iOS): Add a `useLegacy` flag to switch between the old/new iOS implementation (#783)

* wip: unsuspicious changes

* wip: unsuspicious changes v2

* FABRIC NEW IMPL -> OLD IMPL

* wip: bring back useLegacy on the RN side

* wip: bring back duplicate types to fix codegen issues

* wip: remove #705 related code for now

* wip: old/new impl division first draft

* wip: old/new impl division continued

* wip: old/new impl v3

* wip: add a `LEGACY_` prefix to all legacy implementation-related symbols

* wip: fix styles for new implementation on Fabric

* wip: move old/new impl into separate folders

* wip: fix old impl fabric symbol names

* wip: xcode changes

* wip: clean up & unify the naming convention

* wip: fix linter issues

* wip: fix styles for new implementation on Paper

* wip: make Fabric example run on another port by default to make it possible to run both examples in parallel

* wip: implement an abstraction over native commands invocations to reduce branching

* refactor: remove the unnecessary value for boolean props

* fix: bump react-native-safe-area-context to a Fabric-enabled version

* feat: bring back & adjust the `bootstrap-fabric` script

* feat: adjust the home screen title depending on the used architecture

* chore: update example/Podfile.lock

* chore: update an Xcode project file after building

* ci: make next branch events trigger ios/android build workflows

* chore: remove commented-out code related to #705 for now

* chore: add legacy implementation explanation comment

* wip: Android fixes

* fix: unnecessary comma in MainActivity.java

* feat: readme makeover

* chore: bump react-native-screens & react-native-gesture-handler in example

* refactor(android): extract module name to shared variable, add comment for context

* chore: remove unnecessary yarn.lock deps

* chore(ios): bring back removed build flags

* chore(ios): remove unnecessary concurrentRootEnabled method

According to React Native Upgrade Helper, this method is to be removed when updating to RN 0.72:
https://react-native-community.github.io/upgrade-helper/?from=0.71.14&to=0.72.0#RnDiffApp-ios-RnDiffApp-AppDelegate.mm

* fix(android): adjust incorrect param type on Fabric

* chore: remove unnecessary tsconfig.json comment

* chore(ios): bring back (currently unused) code related to #712 and #705

* Release 7.0.0-rc.1

* fix(ios): fix freezing when navigating to same index (#804)

* Release 7.0.0-rc.2

* fix iOS issue

* Change Legacy basic example into the next basic example

* revert documentatation

---------

Co-authored-by: Kacper Rożniata <[email protected]>
Co-authored-by: Piotr Trocki <[email protected]>
Co-authored-by: Oskar Kwaśniewski <[email protected]>
Co-authored-by: Nishan <[email protected]>
Co-authored-by: Kuba Juszczyk <[email protected]>
Co-authored-by: Kuba Juszczyk <[email protected]>
Co-authored-by: Igor Bejnarowicz <[email protected]>
td-miloszdubiel pushed a commit to Transmission-Dynamics/react-native-pager-view that referenced this pull request Jan 29, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants