-
Notifications
You must be signed in to change notification settings - Fork 24.8k
Add support for scrolling a scroll view with a custom duration #1334
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
Conversation
67e4b5f
to
9d3691c
Compare
da0e9ee
to
b86af79
Compare
Maybe we could make scroll position a controlled value and do (sneak peak of the animation API i'm working on) getInitialState: function() {
return { scrollY: new Animated.Value(0) };
}
onWhatever: function() {
this.state.scrollY.animateTiming(150, {duration: 500, easing: Easing.quad});
}
render() {
return <Animated.ScrollView scrollY={this.state.scrollY} />
} Because |
@vjeux: what is the behavior of the scroll view after the animation is finished? Does it stay pinned to y=150, or does a finished animation stop controlling the scroll position? |
It would not stay pinned. But you are right this is super weird One other thing we can do is scrollY(y, animation) Where animation can be TimingAnimation, DecayAnimation, SpringAnimation (currently implemented but we can use any), pre-compute the key frames and send them to native to actually do the interpolation. Would that work? This way, we don't have to implement yet another way to describe those easing functions |
@vjeux does the TimingAnimation, DecayAnimation, etc. stuff already exist somewhere? I can't find it. Or is it in FB's repo |
Not yet, i'm iterating on it inside of facebook codebase, don't want to trash people while working on the api |
@vjeux other thoughts: It's pretty interesting to have the scroll position not stay pinned. This notion of an "ephemeral value" could be used to replace imperative APIs and perhaps remove refs from React. To generalize, this code: render() {
return <X ref="x" />;
}
onEvent() {
this.refs.x.performAction();
} is now: getInitialState() {
return { performAction: new Animated.Boolean(false) };
}
render() {
return <X performAction={this.state.performAction} />;
}
onEvent() {
this.state.performAction.setEphemeralValue(true); // true for one pass
} This may also be the answer to making components like TextInput much more usable. Currently the asynchrony between JS and UIKit is janky and controlled TextInputs aren't usable in production. But I think there's a third type of TextInput -- semi-controlled -- where you generally don't need it to be controlled but occasionally want to set its value to a given string from JS, just like how the scroll view's position generally should not be controlled but sometimes we want to set the position from JS. |
I agree that the prop driven API is interesting...but obviously in order to really make it viable, I think it would need to become idiomatic React...as right now, idiomatic React (at least, the public facing version) seems to be using refs to perform events on components. I think @ide hits the nail on the head when he relates this API to making other components more usable and less imperative. I think there's a lot of power in that idea, and would be curious to see it explored further. That being said...I think that keeping the scrollTo function and expanding on it is a good first step. I would love to add the animation stuff and agree it's better than passing in some weird options object...but I guess we'll just need to wait for what you come up with, @vjeux. Should we keep this open just to remind us that it's here? Or should I close and revisit the refactor once the animation API you're talking about lands? |
@ide your idea of semi-controlled components is fascinating! I have to sleep on it :) I'm sure @sahrens will enjoy it as well. @skevy How urgent is it for you? I plan to have my api open sourced in the next few weeks. I'd love to revisit this once it is in a more advanced state. Would you mind keeping a fork for a while until things has settled? |
It's urgent, but I don't mind keeping the fork. Thanks for the feedback, and I look forward to seeing the new API! |
The current TextInput is already basically semi-controlled because fully-controlled is janky due to async as you mention. If you don't update the value prop in js, the native value won't be overwritten, and if you continuously update the value, there is some buffering to try and reduce the jankiness by not overwriting the native value immediately. Would be nice to have a better solution, perhaps a mechanism to provide a js code snippet to run synchronously on the main thread?
|
Okay, I'll close the pull request for now and will open it back when Animated is released. Thanks for bringing this up! |
@vjeux maybe it's time to open back this issue ? |
Is this something that could viably alleviate some performance issues? What difficulties are there in implementing such a thing?
This idea is very interesting. Are there any inherent problems with making a |
With the natively implemented Animated + gestures, this might actually make sense to do. As for the original issue of specifying a custom duration, the scrollTo API now takes an object |
If someone wants to rebase and rework this with the simpler |
Oh nevermind, stuff is happening in #17422 |
Adds scrollWithCustomDurationTo() to ScrollView.js.
I found that this was necessary when moving a scroll view to accommodate a keyboard -- rather than using the default animation duration, I wanted to animate the scroll view in 250ms to match the duration of the keyboard animation.