如何在 React Native 中进行签名捕获?

问题描述 投票:0回答:4

我试图了解如何在 React Native 中进行签名捕获。我的应用程序是使用

create-react-native-app
Expo
创建的,我希望不必弹出应用程序即可让此功能正常工作。

是否可以将这样的东西包装在网络视图中? https://github.com/szimek/signature_pad

我也看过这个项目,https://github.com/RepairShopr/react-native-signature-capture,但它需要我弹出应用程序并使用

react-native link

寻找有关如何实现此功能的任何建议或建议,同时使我的项目尽可能简单(理想情况下,使用 create-react-native-app,但如果不可能,有人可以向我解释为什么吗?)

react-native expo create-react-native-app signaturepad
4个回答
3
投票

React Native 的工作方式是,React Native 中可用的每个组件都映射到底层平台中的本机组件。

即。 a

<Image />
在 Android 中是
ImageView
,在 iOS 中是
UIImageView.h

Javascript 代码本身在每个平台上的 Javascript 线程中运行,当您在 React Native 中使用组件时,有一个转换层将信息从 JS 传递到 React Native 桥,然后创建相应的本机组件。

默认情况下,React Native 包含以下组件:https://facebook.github.io/react-native/docs/components-and-apis.html#basic-components 这意味着只有这些组件会出现 - React Native 中现成的。如果你想要其他组件,那么你有 2 个选择,要么创建一个“复合”组件,将你的 JS 组件写入其他 JS 组件,要么,如果你的功能需要 React Native 尚未公开的原生组件,则编写你自己的“ native”组件向您的 React Native 代码公开某些本机功能。

Expo 的工作方式是,他们包装了 React Native 和一些第三方组件,并将其构建在他们的应用程序中。您不能使用他们不支持的第 3 方本机组件的原因是,当使用该组件时,应用程序本身没有从 JS 到本机 Android/iOS 视图的转换代码。

因此,要完成您所要求的操作,您需要找到 Expo 已包含在其平台/应用程序中的“本机”绘图组件。或者您需要找到一个使用其他默认 React Native 组件(或 Expo 支持的其他组件)构建的“复合”绘图组件。

即。在 Android 上,我可能会使用 Canvas 视图构建它,但据我所知,React Native 本身并不支持该对象,所以我可能会自己编写这个,等等。

Expo 很难支持所有第 3 方“原生”组件,因为 React Native 是开源的,而且迭代速度如此之快,以至于大多数社区构建的组件并不总是最新的,或者它们可能会相互冲突。


2
投票

我正在使用react-native-signature-capture。 在 Android 和 iOS 上都能正常工作。


1
投票

我知道已经有一段时间了,但是这里有一篇有趣的文章:https://blog.expo.io/drawing-signatures-with-expo-25d1629ca1ac

等等,但是怎么样?

使用“expo-pixi”,您可以添加一个组件,让您选择画笔的颜色、粗细和不透明度。然后,当您的用户抬起手指时,您会收到回调。从那里,您可以截取透明视图的屏幕截图,或者获取原始点数据(如果您需要的话)。


0
投票

在尝试了上述所有解决方案以及其他 GitHub 问题超过 24 小时后,我最终使用了这个解决方案:

安装这些软件包

expo install react-native-svg
npm install  git+https://github.com/MarangoniEduardo/expo-draw

签名组件代码

import React, { useState, useRef } from "react";
import { View, Text, TouchableOpacity, StyleSheet } from "react-native";
import ExpoDraw from "expo-draw";
import { captureRef as takeSnapshotAsync } from "react-native-view-shot";

const DrawSignatureScreen = (props) => {
 
  const [strokes, setStrokes] = useState([]); // Added state for strokes
  const signatureRef = useRef(null);

  const clearCanvas = async () => {
    signatureRef.current.clear();
    setStrokes([]); // Clear strokes
  };

  const saveCanvas = async () => {
    try {
      const signature_result = await takeSnapshotAsync(signatureRef.current, {
        format: "jpg", // 'png' also supported
        quality: 0.5, // quality 0 for very poor 1 for very good
        result: "tmpfile",
      });

      console.log("Signature file:", signature_result);
    } catch (error) {
      console.log(error);
    }
  };

  return (
    <View style={styles.container}>
      <Text style={styles.formTitle}>Enter your signature here</Text>
      <View style={styles.canvasContainer}>
        <ExpoDraw
          strokes={strokes} // Pass strokes to ExpoDraw
          ref={signatureRef}
          containerStyle={styles.canvas}
          rewind={(undo) => console.log("Undo", undo)}
          clear={(clear) => console.log("Clear", clear)}
          color={"#000000"}
          strokeWidth={4}
          enabled={true}
          onChangeStrokes={(strokes) => setStrokes(strokes)} // Update strokes
        />
        <View style={styles.buttonsContainer}>
          <TouchableOpacity style={styles.button} onPress={clearCanvas}>
            <Text style={styles.buttonText}>Reset</Text>
          </TouchableOpacity>
          <TouchableOpacity style={styles.button} onPress={saveCanvas}>
            <Text style={styles.buttonText}>Sign</Text>
          </TouchableOpacity>
        </View>
      </View>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
  },
  formTitle: {
    fontSize: 20,
    marginBottom: 20,
  },
  canvasContainer: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
  },
  canvas: {
    backgroundColor: "rgba(0, 0, 0, 0.01)",
    height: 300,
    width: 500,
  },
  buttonsContainer: {
    flexDirection: "row",
    justifyContent: "space-evenly",
    marginTop: 20,
  },
  button: {
    padding: 10,
    height: 50,
    borderRadius: 10,
    backgroundColor: "green",
    alignItems: "center",
  },
  buttonText: {
    fontSize: 18,
    color: "white",
  },
});

export default DrawSignatureScreen;
© www.soinside.com 2019 - 2024. All rights reserved.