-
Notifications
You must be signed in to change notification settings - Fork 24.4k
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
[ScrollView] Scrolling ends prematurely in ScrollViews embedded in a parent ScrollView #41
Comments
Cc @jordwalke |
Great investigation, @jordanna. The information is very helpful. Scroll views in native know to stop scrolling if something that contains them becomes the responder in JS (like if you were dragging an outer modal view down - that should stop any scroll views from scrolling). My question is, why is the outer scroll view becoming the JS responder? One thing that would cause this is an onScroll occurring on the outer scroll view. |
Ok, I finally got around to looking more into this issue (was sidetracked by animation hacks!). During event extraction in the
Could this be a timing issue with touch moves and scrolls? |
I've also been running into this issue. The setup I have is an outer horizontal/paging
The adverse affects I'm seeing on the expected scrolling behavior of the inner |
I'll look more into this in the coming week, but I believe the correct way to correctly integrate is to do all enabling/disabling of the scroll view completely from JS (it should start out disabled and then become enabled when JS determines it should become the JS responder). This is actually incredibly difficult because UIKit's scroll view doesn't like to work this way and it might involve some trickery. |
Any updates on this one? |
@nicklockwood: Do you know of a way to have |
You could set the scrollEnabled property to NO, or in the viewDidScrollDelegate you could reset the contentOffset to th previous value. |
I tried both of those options. In the former, you cannot reenable it after touches have began, which is what would allow this issue to be fixed (and all future scroll view conflicts). I also tried the later suggestion, but I believe the momentum has issues in that case. |
Running into this issue too - I don't suppose there's been any progress here? |
@vjeux, this is the kind of troubles we're having with native scroll views. The responder system solves it and I don't know how to solve it while using the UIScrollViews. |
Any movement on this one? I have a similar example up on stack overflow (http://stackoverflow.com/questions/29756217/react-native-nested-scrollview-locking-up) that nobody has been able to answer. |
@nicholasstephan Modify
UPDATE: I find if the scroll view is currently animating and wants to become the responder, then it will reject. Line 189 in ScrollResponder.js. So I modify Line 340 and it work for me:
|
Is there any progress here? |
Maybe with subclassing, you can make a https://twitter.com/andy_matuschak/status/559796157241507841 Not sure if that introduces significant lag. |
what do you think, @ide? You seem to have the most experience with nesting and composing scroll views... |
I'm not actively looking into this. Based on what I've heard from other people and from reading this discussion, the solution could be quite hard or non-obvious without advanced knowledge of gesture systems. I have a thought regarding some of the discussion above...
Might be possible through the gesture recognizers by adding a custom gesture recognizer that communicates with the JS layer. I think you can tell UIScrollView's private gesture recognizers to need this custom gesture recognizer to fail -- this might let JS allow/disallow the private gesture recognizers to become active. |
I think @andreic has been looking at this a bit? |
I'm having this issue as well. Any insights into which files to start looking into first? |
any solution? |
ping @andreic 😄 we need you |
+1 Also hitting this nasty one. Would look into it if I had more experience with gesture systems. |
+1 |
1 similar comment
👍 |
Github issues are not working well for us - we are a very small team and and need a way to prioritize. A good way to prioritize is to let people vote on issues and Product Pains lets you do exactly that. You can get an estimate by sorting github issues by the number of comments but it's not that reliable: https://github.com/facebook/react-native/issues?q=is%3Aissue+is%3Aopen+sort%3Acomments-desc |
@brentvatne @ide @mkonicek fair enough, thanks for the explanations |
@toddw - no problem :) thanks for weighing in on ProductPains! |
This has been fixed in this commit 67bf0f1 and should be coming to 0.17. Yay! |
So stoked to see this fixed! Thanks so much! |
@arianitu I still see this issue in latest 0.19, why? |
+1 I still get it |
+1 |
1 similar comment
+1 |
I see this happenning in 0.20 too |
+1 seeing this issue too |
+1 still seeing this issue. is there really no workarounds? Disabling scrolling on the parent causes lots of jerkiness. |
+1,I see this issue in 0.22 too |
+1,I see this issue in 0.22 too |
+1 still seeing it in .20 as well. |
…crash on simulator, on device I got nothing but app freezed)! My app has an old version of JSONKit which is still using MRC. I think JSONKit is not needed if system version is available. Kicking out of JSONKit will make react native stronger. Crash stack: * thread facebook#11: tid = 0xbd672f, 0x000000010a10edeb imobii-waiqin`jk_encode_add_atom_to_buffer(encodeState=0x00007f9b820a1000, objectPtr=22 key/value pairs) + 16971 at JSONKit.m:2807, name = 'com.facebook.React.JavaScript', stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT) frame #0: 0x000000010a10edeb imobii-waiqin`jk_encode_add_atom_to_buffer(encodeState=0x00007f9b820a1000, objectPtr=22 key/value pairs) + 16971 at JSONKit.m:2807 frame facebook#1: 0x000000010a10ef67 imobii-waiqin`jk_encode_add_atom_to_buffer(encodeState=0x00007f9b820a1000, objectPtr=2 key/value pairs) + 17351 at JSONKit.m:2811 frame facebook#2: 0x000000010a10ef67 imobii-waiqin`jk_encode_add_atom_to_buffer(encodeState=0x00007f9b820a1000, objectPtr=25 key/value pairs) + 17351 at JSONKit.m:2811 frame facebook#3: 0x000000010a10e768 imobii-waiqin`jk_encode_add_atom_to_buffer(encodeState=0x00007f9b820a1000, objectPtr=@"3 elements") + 15304 at JSONKit.m:2778 * frame facebook#4: 0x000000010a10a26a imobii-waiqin`-[JKSerializer serializeObject:options:encodeOption:block:delegate:selector:error:](self=0x00007f9b831fbc80, _cmd="serializeObject:options:encodeOption:block:delegate:selector:error:", object=@"3 elements", optionFlags=0, encodeOption=10, block=0x0000000000000000, delegate=0x0000000000000000, selector=<no value available>, error=domain: class name = NSInvocation - code: 0) + 2250 at JSONKit.m:2876 frame facebook#5: 0x000000010a109992 imobii-waiqin`+[JKSerializer serializeObject:options:encodeOption:block:delegate:selector:error:](self=JKSerializer, _cmd="serializeObject:options:encodeOption:block:delegate:selector:error:", object=@"3 elements", optionFlags=0, encodeOption=10, block=0x0000000000000000, delegate=0x0000000000000000, selector=<no value available>, error=domain: class name = NSInvocation - code: 0) + 178 at JSONKit.m:2831 frame facebook#6: 0x000000010a10f700 imobii-waiqin`-[NSArray(self=@"3 elements", _cmd="JSONStringWithOptions:error:", serializeOptions=0, error=domain: class name = NSInvocation - code: 0) JSONStringWithOptions:error:] + 112 at JSONKit.m:2985 frame facebook#7: 0x000000010ac13c02 imobii-waiqin`_RCTJSONStringifyNoRetry(jsonObject=@"3 elements", error=domain: class name = NSInvocation - code: 0) + 338 at RCTUtils.m:49 frame facebook#8: 0x000000010ac13990 imobii-waiqin`RCTJSONStringify(jsonObject=@"3 elements", error=0x0000000000000000) + 128 at RCTUtils.m:77 frame facebook#9: 0x000000010ab5fdfa imobii-waiqin`__27-[RCTContextExecutor setUp]_block_invoke_2(.block_descriptor=<unavailable>, moduleName=@"UIManager") + 218 at RCTContextExecutor.m:363 frame facebook#10: 0x00000001134495cc CoreFoundation`__invoking___ + 140 frame facebook#11: 0x000000011344941e CoreFoundation`-[NSInvocation invoke] + 286 frame facebook#12: 0x000000010db13db3 JavaScriptCore`JSC::ObjCCallbackFunctionImpl::call(JSContext*, OpaqueJSValue*, unsigned long, OpaqueJSValue const* const*, OpaqueJSValue const**) + 451 frame facebook#13: 0x000000010db13926 JavaScriptCore`JSC::objCCallbackFunctionCallAsFunction(OpaqueJSContext const*, OpaqueJSValue*, OpaqueJSValue*, unsigned long, OpaqueJSValue const* const*, OpaqueJSValue const**) + 262 frame facebook#14: 0x000000010db14bad JavaScriptCore`long long JSC::APICallbackFunction::call<JSC::ObjCCallbackFunction>(JSC::ExecState*) + 573 frame facebook#15: 0x000000010dade340 JavaScriptCore`JSC::LLInt::setUpCall(JSC::ExecState*, JSC::Instruction*, JSC::CodeSpecializationKind, JSC::JSValue, JSC::LLIntCallLinkInfo*) + 528 frame facebook#16: 0x000000010dae535d JavaScriptCore`llint_entry + 22900 frame facebook#17: 0x000000010dadf7d9 JavaScriptCore`vmEntryToJavaScript + 326 frame facebook#18: 0x000000010d9b1959 JavaScriptCore`JSC::JITCode::execute(JSC::VM*, JSC::ProtoCallFrame*) + 169 frame facebook#19: 0x000000010d9985ad JavaScriptCore`JSC::Interpreter::executeCall(JSC::ExecState*, JSC::JSObject*, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&) + 493 frame facebook#20: 0x000000010d76cb7e JavaScriptCore`JSC::call(JSC::ExecState*, JSC::JSValue, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&) + 62 frame facebook#21: 0x000000010d929a55 JavaScriptCore`JSC::callGetter(JSC::ExecState*, JSC::JSValue, JSC::JSValue) + 149 frame facebook#22: 0x000000010dad49fb JavaScriptCore`llint_slow_path_get_by_id + 2203 frame facebook#23: 0x000000010dae22f0 JavaScriptCore`llint_entry + 10503 frame facebook#24: 0x000000010dae5368 JavaScriptCore`llint_entry + 22911 frame facebook#25: 0x000000010dae52fd JavaScriptCore`llint_entry + 22804 frame facebook#26: 0x000000010dae5368 JavaScriptCore`llint_entry + 22911 frame facebook#27: 0x000000010dae5368 JavaScriptCore`llint_entry + 22911 frame facebook#28: 0x000000010dae52fd JavaScriptCore`llint_entry + 22804 frame facebook#29: 0x000000010dae5368 JavaScriptCore`llint_entry + 22911 frame facebook#30: 0x000000010dae5368 JavaScriptCore`llint_entry + 22911 frame facebook#31: 0x000000010dae5368 JavaScriptCore`llint_entry + 22911 frame facebook#32: 0x000000010dae552a JavaScriptCore`llint_entry + 23361 frame facebook#33: 0x000000010dae5368 JavaScriptCore`llint_entry + 22911 frame facebook#34: 0x000000010dae5368 JavaScriptCore`llint_entry + 22911 frame facebook#35: 0x000000010dadf7d9 JavaScriptCore`vmEntryToJavaScript + 326 frame facebook#36: 0x000000010d9b1959 JavaScriptCore`JSC::JITCode::execute(JSC::VM*, JSC::ProtoCallFrame*) + 169 frame facebook#37: 0x000000010d998264 JavaScriptCore`JSC::Interpreter::execute(JSC::ProgramExecutable*, JSC::ExecState*, JSC::JSObject*) + 10404 frame facebook#38: 0x000000010d7a8786 JavaScriptCore`JSC::evaluate(JSC::ExecState*, JSC::SourceCode const&, JSC::JSValue, WTF::NakedPtr<JSC::Exception>&) + 470 frame facebook#39: 0x000000010d9f6fb8 JavaScriptCore`JSEvaluateScript + 424 frame facebook#40: 0x000000010ab6379e imobii-waiqin`__68-[RCTContextExecutor executeApplicationScript:sourceURL:onComplete:]_block_invoke.264(.block_descriptor=<unavailable>) + 414 at RCTContextExecutor.m:589 frame facebook#41: 0x000000010ab63262 imobii-waiqin`__68-[RCTContextExecutor executeApplicationScript:sourceURL:onComplete:]_block_invoke(.block_descriptor=<unavailable>) + 498 at RCTContextExecutor.m:589 frame facebook#42: 0x000000010ab63df8 imobii-waiqin`-[RCTContextExecutor executeBlockOnJavaScriptQueue:](self=0x00007f9b832f6040, _cmd="executeBlockOnJavaScriptQueue:", block=0x00007f9b80c92970) + 248 at RCTContextExecutor.m:627 frame facebook#43: 0x000000010eb1d7a7 Foundation`__NSThreadPerformPerform + 283 frame facebook#44: 0x0000000113486301 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17 frame facebook#45: 0x000000011347c22c CoreFoundation`__CFRunLoopDoSources0 + 556 frame facebook#46: 0x000000011347b6e3 CoreFoundation`__CFRunLoopRun + 867 frame facebook#47: 0x000000011347b0f8 CoreFoundation`CFRunLoopRunSpecific + 488 frame facebook#48: 0x000000010ab5e41b imobii-waiqin`+[RCTContextExecutor runRunLoopThread](self=RCTContextExecutor, _cmd="runRunLoopThread") + 363 at RCTContextExecutor.m:284 frame facebook#49: 0x000000010ebc012b Foundation`__NSThread__start__ + 1198 frame facebook#50: 0x00000001140869b1 libsystem_pthread.dylib`_pthread_body + 131 frame facebook#51: 0x000000011408692e libsystem_pthread.dylib`_pthread_start + 168 frame facebook#52: 0x0000000114084385 libsystem_pthread.dylib`thread_start + 13
Still seeing the same issue in 0.41! |
+1, also happening in 0.41 |
+1, 0.46.1 |
+1, 0.48.3 |
+1, 0.51.0 |
+1, 0.50.3, And I try the following way ,but not use. UPDATE: I find if the scroll view is currently animating and wants to become the responder, then it will reject. Line 189 in ScrollResponder.js. So I modify Line 340 and it work for me: scrollResponderIsAnimating: function(): boolean { |
+1 0.53.0 |
+1 0.52.0 My scenario is using a root view in a native view controller as a separated view on iOS platform, the root view contains a When I pop back to the previous view controller, I press down the My solution is return false from |
You can see this behavior in the UIExplorer app's
<ScrollView>
example. Fling to initiate a scroll in an innerScrollView
and fling again (before scrolling ends) to increase scroll momentum. Often times, this causes the scrolling to stop.I haven't had gone through all of the
ResponderEventPlugin
code yet, but I'm seeing that whenResponderEventPlugin.extractEvents
is called, thetopLevelTargetID
is sometimes incorrect.The touches that unintentionally stop scrolling appear to be associated with the parent
ScrollView
instead of the innerScrollView
's content. I traced this down toRTCScrollView._shouldDisableScrollInteraction
where[self isDescendantOfView:JSResponder]
is sometimesYES
. Forcing it to always returnNO
fixes the issue, but I'm pretty sure that's not the intention of this method :)The text was updated successfully, but these errors were encountered: