react-native-signature-canvas
react-native-signature-canvas copied to clipboard
Only dots are drawn on Android
Hello! When I try to draw something fast instead of the expected shape I see only one dot. I've noticed that in this case calls only onBegin prop, onEnd is not calling.
Could you please tell what can i do with this problem?
How I use the component: (onBegin() and onEnd() are needed for disabling and enabling the parent component's scrollView)
<Signature
ref={ref}
onOK={handleSignature}
webStyle={webStyle}
descriptionText={signatureError}
trimWhitespace={true}
onBegin={() => {
!pressed ? setSignatureErrorText("") : {}
onBegin ? onBegin() : {};
}}
onEnd={() => {
ref.current?.readSignature();
onEnd ? onEnd() : {};
}}
/>
Hope you can provide complete code that can run
Sorry for taking so long Here is my component and video with behavior playback
On the video you can see that when I've got the dot inside the signature field (making a sharp move) I am not able to use scroll anymore
https://user-images.githubusercontent.com/36168154/111494165-4d101d80-874f-11eb-9385-a7a1eb53d3b8.mov
import React, {useState, useRef } from 'react';
import { StyleSheet, ScrollView, View, Dimensions, Pressable, Text } from 'react-native';
import Signature, { SignatureViewRef } from 'react-native-signature-canvas';
const windowWidth = Dimensions.get('window').width
const SignatureScreen = () => {
const [isScrollEnabled, setScrollEnabled] = useState(true)
const ref = useRef<SignatureViewRef>(null);
const [signatureValue, setSignatureValue] = useState("");
const handleSignature = (signature: any) => {
setSignatureValue(signature)
};
const onClearButtonPress = () => {
setScrollEnabled(true)
setSignatureValue("")
ref.current?.clearSignature()
}
const webStyle = `
.m-signature-pad--body {
position: absolute;
bottom: 0px;
top: 0px;
left: 0px;
right: 0px;
border: none;
}
.m-signature-pad--footer
.button.clear {
display: none
}
.button.save {
display: none
}
.m-signature-pad--footer {
display: none
}
`;
return (
<ScrollView scrollEnabled={isScrollEnabled} contentContainerStyle={styles.container}>
<View style={[styles.signatureWrapper, { height: windowWidth}]}>
<Signature
ref={ref}
onOK={handleSignature}
webStyle={webStyle}
trimWhitespace={true}
onBegin={() => setScrollEnabled(false)}
onEnd={() => {
ref.current?.readSignature();
setScrollEnabled(true)
}}
/>
</View>
<View style={styles.bottomButtons}>
<Pressable style={styles.transparentButton} onPress={onClearButtonPress} >
<Text>clear signature</Text>
</Pressable>
</View>
<View style={{height: 500}}>
<Text>White space</Text>
</View>
</ScrollView>
)
}
const styles = StyleSheet.create({
container: {
padding: 20,
},
signatureWrapper: {
padding: 2,
borderWidth: 2,
borderRadius: 10
},
bottomButtons: {
alignItems: 'center'
},
transparentButton: {
paddingTop: 7,
paddingBottom: 11,
marginTop: 14,
marginBottom: 10
},
text: {
paddingTop: 12,
paddingBottom: 15,
color: "#1f2229",
fontSize: 15
}
})
export default SignatureScreen;
Sorry for keeping you waiting. I used your code to reproduce this problem. I think this problem is caused by using ScrollView. The onEnd event is not triggered when the scroll is too fast. When I set scrollEnabled to false, it It works normally. I have no good solution for the time being. If you have a good solution, please PR and sorry again.
Unfortunately I can't do without scrolling(( Thank you for your time! If I find a solution, I will PR.
Facing the same issue on Android with Modal. Any solution would be appreciated @YanYuanFE
Same here even without a scroll view, this happens on certain devices. I narrowed it down to the fact that if the signature screen is the first one rendered it works, but having a transition to it from any other screen breaks the behavior, and only dots are drawn.
I had the same issue.
I have my SignaturePad inside the Modal Screen .
My parent component of the Screen was a TouchableOpacity (so that I can close modal on clicking outside ) and I was wrapping my SignaturePad inside it and it was causing this issue.
But it worked properly in IOS
After replacing my TouchableOpacity to View the issue didn't occurred again.
Eventually I ended up adding a close button to close my modal screen.
I hope this helps someone who has similar component like mine.
Same problem if signature too fast, the component cannot be used in the report with a scrollView
Try to add androidHardwareAccelerationDisabled={true} to your SignatureScreen component. I think on Android it may be related to hardware acceleration. Turning it off will slow component performance a bit, but you should get a better plot.
Same here even without a scroll view, this happens on certain devices. I narrowed it down to the fact that if the signature screen is the first one rendered it works, but having a transition to it from any other screen breaks the behavior, and only dots are drawn.
I'm having the same issue, is there any way to fix this?
@jn394 "I had the same error, I had wrapped my SignatureScreen in the following code block:
<View onLayout={onSignatureLayout} {...panResponder.panHandlers} style={{ width: imgWidth, height: imgHeight }}
Removing it solved my error, I hope it helps you."
I used the nestedScrollEnabled={true} prop with the WebView component, and that resolved the issue and I used patch-package to create a patch file.
<WebView bounces={false} source={source} ref={webViewRef} onError={renderError} onMessage={getSignature} javaScriptEnabled={true} scrollEnabled={scrollable} androidLayerType="hardware" style={[webviewContainerStyle]} onLoadEnd={() => setLoading(false)} nestedScrollEnabled={true} />
Same problem here... even though it works perfectly on iOS
None of the solutions above worked for me.
Same problem here... even though it works perfectly on iOS
None of the solutions above worked for me.
10 seconds later i found out that i was wrapping my canvas with TouchableWithoutFeedback in my dynamic form, so i removed and it works fine.
It was like this:
return (
<TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false}>
<View>
{renderInputType(text)}
</View>
</TouchableWithoutFeedback>
);
now it looks like this ( when text == A it'll render the canvas ) :
return text !== 'A' ? (
<TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false}>
<View>
{renderInputType(text)}
</View>
</TouchableWithoutFeedback>
) : (
<View>
{renderInputType(text)}
</View>
);
androidLayerType="hardware"
worked for me !