Fix layout calculations (#2816)

zio/stable
dan 2024-02-09 06:20:41 +00:00 committed by GitHub
parent d36b91fe67
commit 43b447e5f4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 31 additions and 11 deletions

View File

@ -68,15 +68,12 @@ export const PagerWithHeader = React.forwardRef<PagerRef, PagerWithHeaderProps>(
setTabBarHeight(Math.round(height)) setTabBarHeight(Math.round(height))
} }
}) })
const onHeaderOnlyLayout = useNonReactiveCallback( const onHeaderOnlyLayout = useNonReactiveCallback((height: number) => {
(evt: LayoutChangeEvent) => { if (height > 0) {
const height = evt.nativeEvent.layout.height // The rounding is necessary to prevent jumps on iOS
if (height > 0 && isHeaderReady) { setHeaderOnlyHeight(Math.round(height))
// The rounding is necessary to prevent jumps on iOS }
setHeaderOnlyHeight(Math.round(height)) })
}
},
)
const renderTabBar = React.useCallback( const renderTabBar = React.useCallback(
(props: RenderTabBarFnProps) => { (props: RenderTabBarFnProps) => {
@ -224,7 +221,7 @@ let PagerTabBar = ({
testID?: string testID?: string
scrollY: SharedValue<number> scrollY: SharedValue<number>
renderHeader?: () => JSX.Element renderHeader?: () => JSX.Element
onHeaderOnlyLayout: (e: LayoutChangeEvent) => void onHeaderOnlyLayout: (height: number) => void
onTabBarLayout: (e: LayoutChangeEvent) => void onTabBarLayout: (e: LayoutChangeEvent) => void
onCurrentPageSelected?: (index: number) => void onCurrentPageSelected?: (index: number) => void
onSelect?: (index: number) => void onSelect?: (index: number) => void
@ -236,11 +233,34 @@ let PagerTabBar = ({
}, },
], ],
})) }))
const headerRef = React.useRef(null)
React.useEffect(() => {
// Fire when layout *becomes* ready.
// We can't rely on onLayout alone because it won't fire if layout is the same.
// We can't rely on this effect alone because it won't fire if layout changes later.
if (isHeaderReady) {
// @ts-ignore
headerRef.current!.measure(
(_x: number, _y: number, _width: number, height: number) => {
onHeaderOnlyLayout(height)
},
)
}
}, [isHeaderReady, onHeaderOnlyLayout])
return ( return (
<Animated.View <Animated.View
pointerEvents="box-none" pointerEvents="box-none"
style={[styles.tabBarMobile, headerTransform]}> style={[styles.tabBarMobile, headerTransform]}>
<View onLayout={onHeaderOnlyLayout} pointerEvents="box-none"> <View
ref={headerRef}
pointerEvents="box-none"
collapsable={false}
onLayout={e => {
if (isHeaderReady) {
onHeaderOnlyLayout(e.nativeEvent.layout.height)
}
}}>
{renderHeader?.()} {renderHeader?.()}
</View> </View>
<View <View