How do you prevent over-scrolling using react-native ScrollView.scrollTo()? - react-native

After the user does some action I want to scroll to a particular section within a ScrollView, which I'm doing using this code:
this.refs.detailsView.measure((x, y, width, height, pageX, pageY) => {
this.refs.homeScrollView.scrollTo({ x: 0, y: pageY - 64, animated: true });
});
The problem is the "detailsView" View is near the bottom of the ScrollView and on the largest iPhones, scrollTo() ends up scrolling past the bottom of ScrollViews "natural" max scroll point and you can see the ScrollViews background colour (dary grey) as though you over-scrolled using touch gestures...the components in the ScrollView have the green background colour.
Does anyone have a suggestion for how to prevent this "over-scrolling" when using the ScrollView.scrollTo() function?
react-native: v0.36

This disables the scrollview from bouncing past its limit
bounces={false}

Related

React Native onScroll problem when holding my finger up to ScrollView

<ScrollView
onScroll={(event)=>{
const top = event.nativeEvent.contentOffset.y;
setTop(top);
}}
>
With my code above contentOffset y updated only when scroll ScrollView abruptly without holding my finger up to ScrollView but if I hold my finger up when scroll the contentOffset y doesn't updated.
I noticed this happening for all onScroll function.
What I want to achieve:
I want on scroll ScrollView contentOffset y update.
Using Animated.ScrollView instead of ScrollView maybe help you. Have a look at this https://eveningkid.medium.com/animated-and-react-native-scrollviews-de701f1b1ce5

React Native - Scrollview - Apply a zoom using a method/function not pinch

As the zoomScale parameter does not seem to affect the initial zoom level, I would like to set a zoom on my ScrollView using a method/function.
I found that via the ScrollView reference, I can get the responder and then apply scrollResponderZoomTo but it's iOS only.
Is there a way to manipulate the zoom of a ScrollView by another way than the pinch gesture?
Answering my own question, it's possible to use the function scrollResponderZoomTo on the responder of the ScrollView via the reference of the component :
...
<ScrollView
ref={this.scrollViewRef}
...
And a call like this :
this.scrollViewRef.current?.getScrollResponder().scrollResponderZoomTo({
x: viewContentOffsetX || 0,
y: viewContentOffsetY || 0,
width: widthOfTheVisiblePart,
height: heightOfTheVisiblePart,
animated: false})
Up to a function to calculate the visible part based on the expected zoom value

Hold Position of ScrollView when adding data

I am trying to make it so whenever something new is rendered into a scroll view, the scroll view will stay put and not bump up and down. Right now if a new component is rendered in, the scrollview appears to be reset to 0.
Is there a way to stop this behavior, and hold position?
Right now for the scrollview I am using:
handleScrollt(event){
this.scroll = event.nativeEvent.contentOffset.y
}
handleSizet(width, height){
if (this.scroll) {
const position = this.scroll + height - this.height
this.refs.sv.scrollTo({x: 0, y: position, animated: false})
}
this.height = height
}
<ScrollView
ref="sv"
scrollEventThrottle={16}
onScroll={this.handleScrollt.bind(this)}
onContentSizeChange={this.handleSizet.bind(this)}
The issue with this is the scrollview will render briefly, before then scrolling to the correct offset. So it seems like theres a brief splash of the top of the screen
you have to define a height for the scrollview.
If the scrollview is supposed to cover an entire View you can get the view's height by:
<View style={styles.contactView} onLayout={(event) => {
var contactViewY = event.nativeEvent.layout.y;
this.setState({contactViewY: contactViewY})
}}>
and then give it to the scrollview
<ScrollView style={[styles.contactScroller, {height: this.state.contactViewY}]}>
Bear in mind that the onLayout method is called immediately once the layout has been calculated, so if the view's height changes later, this two lines of code alone won't update it.
You should try maintainVisibleContentPosition.
Example:
<ScrollView
{...props}
maintainVisibleContentPosition={{
minIndexForVisible: 0,
}}
/>
From the docs:
maintainVisibleContentPosition
When set, the scroll view will adjust the scroll position so that the
first child that is currently visible and at or beyond
minIndexForVisible will not change position. This is useful for lists
that are loading content in both directions, e.g. a chat thread, where
new messages coming in might otherwise cause the scroll position to
jump. A value of 0 is common, but other values such as 1 can be used
to skip loading spinners or other content that should not maintain
position.

How do I make Scrollview auto scroll when the content size changes in React Native

I currently have a vertical ScrollView that has many expandable cards inside. When one of the cards expands, its height will increase by Y, and therefore the ScrollView content size's height will increase by Y.
I want to make the ScrollView automatically scroll by Y when the content size increases, and scroll by -Y when the content size decreases. How should I achieve this?
You can use "onContentSizeChange", this will return new height after change your view. It's work for me.
<ScrollView
ref={scrollView => {
this.scrollView = scrollView;
}}
onContentSizeChange={(contentWidth, contentHeight) => {
console.log('contentHeight :==> \n', contentHeight);
this.scrollView.scrollTo({
x: 0,
y: contentHeight + YOUR_VIEW_HEIGHT - SCREEN_HEIGTH,
animated: true,
});
}}
>
...
YOUR_VIEW_HEIGHT will get from View's onLayout method.

Immutable view inside zoomable scrollview [react-native]

i'd like to know if it's possible to put a View inside a zoomable ScrollView but when the user zooms the scrollview, the view's size wont change. The view must be inside the scrollview because the image on the scrollview is bigger than the screen and i`ll render the view overlaying the image in a precise x:y position.
thanks
kinda extreme go horse but if you put the prop onScroll inside scrolView you can get the zoom and divide the width/height of the view by the zoomScale
onScroll={(event) => this.setState({ zoomScale:event.nativeEvent.zoomScale})}