react-native-pinchable
react-native-pinchable copied to clipboard
Updating ScrollView content while view is pinched in makes app unresponsive
Hi. We are displaying array of images in ScrollView and if we push new images while the Pinchable component is pinched in, the app is covered with gray overlay, which can't be discarded and makes the app unresponsive.
Here is simple code for reproduction. Launch the app, zoom in and wait for the timeout in useEffect
import React, { useEffect, useState } from 'react'
import { ScrollView, View, Image, Dimensions } from 'react-native'
import Pinchable from 'react-native-pinchable'
export default function App() {
const [sources, setSources] = useState(
new Array(20).fill(0).map((_, index) => 'https://picsum.photos/id/' + index + '/200/300'),
)
useEffect(() => {
setTimeout(() => {
const newSources = new Array(20)
.fill(0)
.map((_, index) => 'https://picsum.photos/id/' + (20 + index) + '/200/300')
setSources(c => [...c, ...newSources])
}, 5000)
}, [])
return (
<View style={{ flex: 1 }}>
<ScrollView pinchGestureEnabled={false}>
{sources.map((image, index) => (
<Pinchable key={index} minimumZoomScale={1} maximumZoomScale={3}>
<Image
style={{ width: Dimensions.get('window').width, height: 300 }}
resizeMode="cover"
source={{ uri: image }}
/>
</Pinchable>
))}
</ScrollView>
<View style={{ flex: 1 }} />
</View>
)
}
Here is video of the code above:
https://user-images.githubusercontent.com/25827002/170460253-a585d4f0-6d3a-4214-a4fe-725ab5ed9d30.mp4
In the place we are using this Pinchable component it behaves a little bit different and if I try to pinch in (after the error happens), the app crashes with following error.
*** Terminating app due to uncaught exception 'CALayerInvalidGeometry', reason: 'CALayer position contains NaN: [nan nan]. Layer: <CALayer:0x600002bfe420; position = CGPoint (206 448); bounds = CGRect (0 0; 0 0); delegate = <RNPinchableView: 0x143cde530; reactTag: 10717; frame = (nan nan; 0 0); anchorPoint = (inf, inf); gestureRecognizers = <NSArray: 0x60000218e1c0>; layer = <CALayer: 0x600002bfe420>>; sublayers = (<CALayer: 0x60000282cb80>); opaque = YES; allowsGroupOpacity = YES; anchorPoint = CGPoint (inf inf); transform = CATransform3D (1 0 0 0; 0 1 0 0; 0 0 1 0; 0 0 0 1); borderColor = (null)>'
*** First throw call stack:
(
0 CoreFoundation 0x000000010b8c7d70 __exceptionPreprocess + 236
1 libobjc.A.dylib 0x0000000108b1614c objc_exception_throw + 56
2 CoreFoundation 0x000000010b8c7c40 -[NSException initWithCoder:] + 0
3 QuartzCore 0x000000010b517afc -[CALayer setPosition:] + 384
4 QuartzCore 0x000000010b5181d8 -[CALayer setFrame:] + 424
5 UIKitCore 0x0000000120f7ffa4 -[UIView(Geometry) setFrame:] + 428
6 ZootMobileApp 0x0000000103c993f8 -[RNPinchableView handlePinchGesture:] + 1156
7 UIKitCore 0x000000012054eee0 -[UIGestureRecognizerTarget _sendActionWithGestureRecognizer:] + 52
8 UIKitCore 0x000000012055820c _UIGestureRecognizerSendTargetActions + 112
9 UIKitCore 0x000000012055511c _UIGestureRecognizerSendActions + 316
10 UIKitCore 0x0000000120554720 -[UIGestureRecognizer _updateGestureForActiveEvents] + 632
11 UIKitCore 0x0000000120548d90 _UIGestureEnvironmentUpdate + 2036
12 UIKitCore 0x0000000120548134 -[UIGestureEnvironment _updateForEvent:window:] + 736
13 UIKitCore 0x0000000120a74350 -[UIWindow sendEvent:] + 4304
14 UIKitCore 0x0000000120a4c0fc -[UIApplication sendEvent:] + 784
15 UIKitCore 0x0000000120ada59c __dispatchPreprocessedEventFromEventQueue + 7720
16 UIKitCore 0x0000000120adc620 __processEventQueue + 6764
17 UIKitCore 0x0000000120ad4540 __eventFetcherSourceCallback + 184
18 CoreFoundation 0x000000010b836234 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24
19 CoreFoundation 0x000000010b836134 __CFRunLoopDoSource0 + 204
20 CoreFoundation 0x000000010b8354c4 __CFRunLoopDoSources0 + 256
21 CoreFoundation 0x000000010b82fa18 __CFRunLoopRun + 744
22 CoreFoundation 0x000000010b82f218 CFRunLoopRunSpecific + 572
23 GraphicsServices 0x000000011173b60c GSEventRunModal + 160
24 UIKitCore 0x0000000120a2da98 -[UIApplication _run] + 992
25 UIKitCore 0x0000000120a32634 UIApplicationMain + 112
26 ZootMobileApp 0x0000000102d43dd0 main + 104
27 dyld 0x00000001076b9cd8 start_sim + 20
28 ??? 0x000000010740108c 0x0 + 4416606348
29 ??? 0x303d000000000000 0x0 + 3475934487399890944
)
libc++abi: terminating with uncaught exception of type NSException
dyld4 config: DYLD_ROOT_PATH=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot DYLD_LIBRARY_PATH=/Users/pavelgric/Library/Developer/Xcode/DerivedData/ZootMobileApp-cwmmojyrqvickmafcfxbhvwcllaw/Build/Products/Debug-iphonesimulator:/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/usr/lib/system/introspection DYLD_INSERT_LIBRARIES=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/usr/lib/libBacktraceRecording.dylib:/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/usr/lib/libMainThreadChecker.dylib:/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/Developer/Library/PrivateFrameworks/DTDDISupport.framework/libViewDebuggerSupport.dylib DYLD_FRAMEWORK_PATH=/Users/pavelgric/Library/Developer/Xcode/DerivedData/ZootMobileApp-cwmmojyrqvickmafcfxbhvwcllaw/Build/Products/Debug-iphonesimulator
terminating with uncaught exception of type NSException
*** Terminating app due to uncaught exception 'CALayerInvalidGeometry', reason: 'CALayer position contains NaN: [nan nan]. Layer: <CALayer:0x600002bfe420; position = CGPoint (206 448); bounds = CGRect (0 0; 0 0); delegate = <RNPinchableView: 0x143cde530; reactTag: 10717; frame = (nan nan; 0 0); anchorPoint = (inf, inf); gestureRecognizers = <NSArray: 0x60000218e1c0>; layer = <CALayer: 0x600002bfe420>>; sublayers = (<CALayer: 0x60000282cb80>); opaque = YES; allowsGroupOpacity = YES; anchorPoint = CGPoint (inf inf); transform = CATransform3D (1 0 0 0; 0 1 0 0; 0 0 1 0; 0 0 0 1); borderColor = (null)>'
CoreSimulator 802.6.1 - Device: iPhone 11 Pro Max (98939DCB-055B-4061-8565-431AE3AC31D6) - Runtime: iOS 15.5 (19F70) - DeviceType: iPhone 11 Pro Max
I have the same experience and a similar error. The error does not happen consistently though. However it only happens on iOS, not on android.
CALayer position contains NaN: [nan nan]. Layer: <CALayer:0x281d10d80; position = CGPoint (212 321); bounds = CGRect (0 0; 0 0); delegate = <RNPinchableView: 0x11a9795f0; reactTag: 5385; frame = (nan nan; 0 0); anchorPoint = (inf, inf); gestureRecognizers = <NSArray: 0x2810e3210>; layer = <CALayer: 0x281d10d80>>; sublayers = (<CALayer: 0x281d5b860>); opaque = YES; allowsGroupOpacity = YES; anchorPoint = CGPoint (inf inf); transform = CATransform3D (1 0 0 0; 0 1 0 0; 0 0 1 0; 0 0 0 1); borderColor = (null)> at 0 CoreFoundation 0x000000018abc929c 6B22DD81-3585-3BE6-BC77-BA19810EC0F2 + 627356 at 1 libobjc.A.dylib 0x00000001a38f9744 objc_exception_throw + 60 at 2 CoreFoundation 0x000000018ac20390 6B22DD81-3585-3BE6-BC77-BA19810EC0F2 + 983952 at 3 QuartzCore 0x000000018e894ebc DF21293E-9DBF-37A5-8506-D0C7F3D8646C + 143036 at 4 QuartzCore 0x000000018e94f5fc DF21293E-9DBF-37A5-8506-D0C7F3D8646C + 906748 at 5 QuartzCore 0x000000018e9676c8 DF21293E-9DBF-37A5-8506-D0C7F3D8646C + 1005256 at 6 UIKitCore 0x000000018d135c7c 137A95AA-DA6D-332C-BC01-E13BB9B6E317 + 1604732 at 7 Solebich 0x0000000100f07a4c -[RNPinchableView handlePinchGesture:] + 1156 at 8 UIKitCore 0x000000018d18be20 137A95AA-DA6D-332C-BC01-E13BB9B6E317 + 1957408 at 9 UIKitCore 0x000000018d155490 137A95AA-DA6D-332C-BC01-E13BB9B6E317 + 1733776 at 10 UIKitCore 0x000000018d11e990 137A95AA-DA6D-332C-BC01-E13BB9B6E317 + 1509776 at 11 UIKitCore 0x000000018d1577d8 137A95AA-DA6D-332C-BC01-E13BB9B6E317 + 1742808 at 12 UIKitCore 0x000000018d1103ac 137A95AA-DA6D-332C-BC01-E13BB9B6E317 + 1450924 at 13 UIKitCore 0x000000018d14375c 137A95AA-DA6D-332C-BC01-E13BB9B6E317 + 1660764 at 14 UIKitCore 0x000000018d150a1c 137A95AA-DA6D-332C-BC01-E13BB9B6E317 + 1714716 at 15 UIKitCore 0x000000018d2fe6fc 137A95AA-DA6D-332C-BC01-E13BB9B6E317 + 3475196 at 16 UIKitCore 0x000000018d124318 137A95AA-DA6D-332C-BC01-E13BB9B6E317 + 1532696 at 17 UIKitCore 0x000000018d119070 137A95AA-DA6D-332C-BC01-E13BB9B6E317 + 1486960 at 18 UIKitCore 0x000000018df6a574 137A95AA-DA6D-332C-BC01-E13BB9B6E317 + 16500084 at 19 UIKitCore 0x000000018d786d5c 137A95AA-DA6D-332C-BC01-E13BB9B6E317 + 8228188 at 20 UIKitCore 0x000000018de0dedc 137A95AA-DA6D-332C-BC01-E13BB9B6E317 + 15072988 at 21 UIKitCore 0x000000018de0d6a4 137A95AA-DA6D-332C-BC01-E13BB9B6E317 + 15070884 at 22 CoreFoundation 0x000000018abeb414 6B22DD81-3585-3BE6-BC77-BA19810EC0F2 + 766996 at 23 CoreFoundation 0x000000018abfc1a0 6B22DD81-3585-3BE6-BC77-BA19810EC0F2 + 836000 at 24 CoreFoundation 0x000000018ab35694 6B22DD81-3585-3BE6-BC77-BA19810EC0F2 + 22164 at 25 CoreFoundation 0x000000018ab3b05c 6B22DD81-3585-3BE6-BC77-BA19810EC0F2 + 45148 at 26 CoreFoundation 0x000000018ab4ebc8 CFRunLoopRunSpecific + 600 at 27 GraphicsServices 0x00000001a6cba374 GSEventRunModal + 164 at 28 UIKitCore 0x000000018d4c2b58 137A95AA-DA6D-332C-BC01-E13BB9B6E317 + 5327704 at 29 UIKitCore 0x000000018d244090 UIApplicationMain + 364 at 30 Solebich 0x00000001002fe754 main + 104 at 31 dyld 0x0000000104759da4 start + 520
Any solution?
Sadly no, I didn't look into it any further. We used following workaroud, but not sure if it's applicable to you. Our use case is that we first load low resolution images and then replace them with high resolution, so to avoid the crash we just disable the zooming feature while the highres images are loading. Partial example code:
<View
// Disable pinch to zoom until full size images are loaded, otherwise the app may crash
pointerEvents={highResImagesLoaded ? 'auto' : 'none'}
>
<Pinchable minZoom={1} maxZoom={3}>
<Image source={image.source} />
</Pinchable>
</View>
I am also facing this issue; anyone found a fix for this? :/