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

I would like the Height to be scaled according to the children

Open yepMad opened this issue 2 years ago • 7 comments

Describe the feature

I saw that there are numerous issues saying that the height of the PagerView is not according to the height of the children. I wish it was. Is it possible to implement this in the current source code architecture? Is there any direction? I would like to do a PR with this, but first I wanted to know if it's possible.

I saw the workarounds and in my use case they are not enough.

Motivation

I have several pages that have varying sizes. I use LazyPagerView from the new Pre-Release version, so I can't consider the highest height of the first pages.

Related Issues

https://github.com/callstack/react-native-pager-view/issues/436 https://github.com/callstack/react-native-pager-view/issues/386

yepMad avatar Mar 15 '22 00:03 yepMad

@troZee If you can help me with this I would be very grateful.

yepMad avatar Mar 15 '22 00:03 yepMad

Describe the feature

I saw that there are numerous issues saying that the height of the PagerView is not according to the height of the children. I wish it was. Is it possible to implement this in the current source code architecture? Is there any direction? I would like to do a PR with this, but first I wanted to know if it's possible.

I saw the workarounds and in my use case they are not enough.

Motivation

I have several pages that have varying sizes. I use LazyPagerView from the new Pre-Release version, so I can't consider the highest height of the first pages.

Related Issues

#436 #386

I am having same issue. Check out the video I made on issue #531.

I found a fix for the issue. Would be nice if @troZee could patch this for us. Go to file path: node_modules/react-native-pager-view/scr/utils.tsx
comment out line 30 and 31

currently

export const childrenWithOverriddenStyle = (children?: ReactNode) => {
  // Override styles so that each page will fill the parent. Native component
  // will handle positioning of elements, so it's not important to offset
  // them correctly.
  return Children.map(children, (child) => {
    const { props } = child as ReactElement;
    const newProps = {
      ...props,
      style: [
        props.style,
        {
          position: 'absolute',
          flex:1,
          left: 0,
          top: 0,
          right: 0,
          bottom: 0,
          width: undefined,
          height: undefined,
        },
      ],
      collapsable: false,
    };
    return React.cloneElement(child as ReactElement, newProps);
  });
};

to

export const childrenWithOverriddenStyle = (children?: ReactNode) => {
  // Override styles so that each page will fill the parent. Native component
  // will handle positioning of elements, so it's not important to offset
  // them correctly.
  return Children.map(children, (child) => {
    const { props } = child as ReactElement;
    const newProps = {
      ...props,
      style: [
        props.style,
        {
          position: 'absolute',
          flex:1,
          left: 0,
          top: 0,
          right: 0,
          bottom: 0,
          // width: undefined,
          // height: undefined,
        },
      ],
      collapsable: false,
    };
    return React.cloneElement(child as ReactElement, newProps);
  });
};

solved my issue

elmcapp avatar Mar 18 '22 17:03 elmcapp

It is not related to the js part. Rolling back to 5.4.11 fixed the issue.

xmflsct avatar Mar 29 '22 21:03 xmflsct

Rolling back to 5.4.13 fixed for me.

jason-vault avatar Apr 08 '22 14:04 jason-vault

managed to solve this using measureLayout

export const MainSlider: FunctionComponent<Props> = ({ slides }) => {
  const [height, setHeight] = useState<number | string>('100%');
  const parentRefs = useMemo<RefObject<View>[]>(
    () => Array.from({ length: slides.length }).map(() => createRef()),
    [],
  );
  const childRefs = useMemo<RefObject<View>[]>(
    () => Array.from({ length: slides.length }).map(() => createRef()),
    [],
  );

  return (
      <PagerView
        style={{ height: height }}
        initialPage={0}
        orientation="horizontal"
        onPageSelected={(e) => {
          const { position } = e.nativeEvent;

          childRefs[position].current?.measureLayout(
            findNodeHandle(parentRefs[position].current),
            (x, y, width, height) => {
              console.log('got measurement', x, y, width, height);
              setHeight(height);
            },
            () => {
              console.log('measureLayout error')
            },
          );
        }}
      >
        {slides?.map((slide, index) => (
          <View key={index}>
            <View ref={parentRefs[index]}>
              <View ref={childRefs[index]}>
                {variable height content}
              </View>
            </View>
          </View>
        ))}
      </PagerView>
  );
};

mmxdr avatar Jun 28 '22 21:06 mmxdr

@mmxdr too many variable required for this solution

fukemy avatar Jan 12 '23 06:01 fukemy

I use this library in two places. One in a standard page, and another inside a modal (which has an internal scrollview). It seems rolling back the version lets it work with the modal, but then breaks my standard use case?!?!?

Seamus1989 avatar May 22 '24 14:05 Seamus1989