react-native-pager-view icon indicating copy to clipboard operation
react-native-pager-view copied to clipboard

block ability to go to prev/next page

Open Lg0gs opened this issue 5 years ago • 7 comments

I want to scroll only in one direction. How is it possible?

Lg0gs avatar Jul 21 '20 12:07 Lg0gs

Hey @Lg0gs Now, we are not supporting this kind of functionality. I will change this issue into feature request.

In case of any help, feel free to ask here.

troZee avatar Jul 21 '20 12:07 troZee

@troZee Hey, thanks for your reply. I achieved the same result by removing the previous element from the array (I render pages looping through it) and it works as expected.

Lg0gs avatar Jul 21 '20 12:07 Lg0gs

@Lg0gs I will not close this issue, because maybe someone is struggling with this case. I would be great to support it on native part.

troZee avatar Jul 21 '20 12:07 troZee

I am successfully using scrollEnabled prop on AnimatedPagerView like in example and it's working great. Just keeping that value in some state and disable/enable it based on some condition.

LadislavBohm avatar Aug 25 '21 10:08 LadislavBohm

I am successfully using scrollEnabled prop on AnimatedPagerView like in example and it's working great. Just keeping that value in some state and disable/enable it based on some condition.

Could you provide any code snippet ?

troZee avatar Aug 26 '21 09:08 troZee

Sure, I will try to provide a snippet. I am passing pages to pager dynamically so I am keeping them in an array of items of this type:

type WizardPage = {
  title: string;
  component: React.ReactElement;
  enableScroll: boolean;
};

Then I am declaring pager like this:

<AnimatedPagerView
        ref={pageViewRef}
        showPageIndicator={false}
        scrollEnabled={isScrollEnabled}
        onPageSelected={handlePageSelected}>
        {pages.map((page, i) => (
          <View key={i}>{page.component}</View>
        ))}
</AnimatedPagerView>

In my handlePageSelected I am checking whether scroll is enabled for it:

const handlePageSelected = useCallback(
    (e: PagerViewOnPageSelectedEvent) => {
      setIsScrollEnabled(pages[e.nativeEvent.position].enableScroll);
    },
    [pages],
  );

And of course I am keeping isScrollEnabled in a state:

const [isScrollEnabled, setIsScrollEnabled] = useState(true);

So if I have collection of pages that looks like this:

  const pages = useMemo(() => {
    const result: WizardPage[] = [
      {
        title: 'First',
        component: <FirstPage />,
        enableScroll: true,
      },
      {
        title: 'Second',
        component: <SecondPage />,
        enableScroll: false,
      },
      {
        title: 'Third',
        component: <ThirdPage />,
        enableScroll: true,
      }];
   return result;
});

it does not allow user to move from second page by swiping. You can still move user by calling setPage(xxx) after he does some action for example (I'm also handling navigation back to prevent him to leave the page but that's outside this issues scope imo).

LadislavBohm avatar Aug 26 '21 09:08 LadislavBohm

This solution is insufficient, if you scroll quickly, you can get past the blocked page - it seems pageSelected is called a bit slow. Trimming the pages up to the blocked page is a better solution, but still not fully satisfactory because if the user tries to go past the last page, pager view seems to cache the fact that there aren't additional pages, so once we unblock, even if we added pages to the trimmed array, we can't proceed. My workaround has been to change the "key" of the PagerView but then the whole thing needs to rerender (all the pages), so neither solution is perfect.

Ideally whatever is caching the fact that there aren't additional pages, would reset when additional pages are added dynamically.

mikob avatar Jul 30 '22 19:07 mikob