【问题标题】:How do I create a proper text editor in React Native?如何在 React Native 中创建合适的文本编辑器?
【发布时间】:2021-05-29 21:17:03
【问题描述】:

我正在 React Native 上创建一个笔记应用程序,目前文本编辑器是一个增强的 TextInput,具有一些额外的功能,如复制、粘贴、插入日期等。

问题是这非常有限,因为我不能添加行号,也不能更改样式、着色文本等。性能也是大文档的一个问题。

我正在尝试将文本分成几行并每行创建一个文本输入,但出现了一些问题:我无法跨行选择文本,我必须处理单独的击键来捕捉换行符,光标不会' t 在文本输入等之间移动。

根据onKeyPress 文档,另一个问题是我可以捕获软键盘事件,但不能捕获物理键盘事件。

我想知道是否有一个好的解决方案,因为现在使用 TextInputs 似乎无法让我做我需要的事情。

一个好的答案要么是一个好的库,要么是关于如何手动执行此操作的说明,直接使用组件并捕获键盘事件(假设这甚至是可能的)。

为了澄清,我不想要富文本编辑器库,我想要构建它的工具。我也不想使用 webview。

【问题讨论】:

    标签: react-native text-editor rich-text-editor


    【解决方案1】:

    这是迄今为止我发现的最好的东西。它包括将Text 组件作为子组件添加到TextInput。它始于 2015 年,虽然并没有完全解决问题,但它是一个开始。

        <TextInput
          ref={this.textInputRef}
          style={styles.input}
          multiline={true}
          scrollEnabled={true}
          onChangeText={this.onChangeText}
        >{
          lines.map((line, index) => {
            return <Text>{line + '\n'}</Text>;
          })
        }</TextInput>
    

    这也证实了这在 React Native 中并不是一件小事。

    在 React Native GitHub 存储库中提交:Added rich text input support

    根据this,也可以添加图片(但我没有测试过)。

    如果我发现其他内容,我会编辑。

    【讨论】:

      【解决方案2】:

      我稍后会更新(我必须上班),所以我会发布我所拥有的并将我的想法留给 cmets

      import React, { 
          useState, useEffect, useRef,
      } from 'react';
      import { 
          View, StyleSheet, TextInput, Text, useWindowDimensions,
          KeyboardAvoidingView, ScrollView
      } from 'react-native';
      
      
      const TextEditor = ({lineHeight=20}) => {
          const { height, width } = useWindowDimensions()
          // determine max number of TextInputs you can make
          const maxLines = Math.floor(height/lineHeight);
          const [ textLines, setTextLines ] = useState(Array(maxLines).fill(''));
          return ( 
              <KeyboardAvoidingView 
                  style={styles.container}
                  behavior={"height"}
              >
              <ScrollView style={{height:height,width:'100%'}}>
                  {/*Make TextInputs to fill whole screen*/}
                  <View style={{justifyContent:'flex-end'}}>
                      {textLines.map((text,i)=>{
                          let style = [styles.textInput,{height:lineHeight}]
                          // if first line give it extra space to look like notebook paper
                          if(i ==0)
                              style.push({height:lineHeight*3,paddingTop:lineHeight*2})
                          return (
                          <>
                              <TextInput
                                style={style}
                                onChangeText={newVal=>{
                                  textLines[i] = newVal
                                  setTextLines(textLines)
                                }}
                                key={"textinput-"+i}
                              />
                          </>
                          )
                      })}
                  </View>
                  </ScrollView>
            </KeyboardAvoidingView>
        )
      }
      
      const styles = StyleSheet.create({
          container:{
              flex:1,
              // paddingTop:40
          },
          textInput:{
              padding:0,
              margin:0,
              borderBottomColor:'lightblue',
              borderBottomWidth:1,
              width:'100%',
          }
          
      })
      
      export default TextEditor
      

      这就是我的想法:

      • 将其包装在 ScrollView 中,如果最后一个 TextInput 处于焦点位置且已达到最大字符限制,则使用 onEndReached 属性呈现额外的 TextInput
      • 将所有文本输入值存储在一个数组中

      【讨论】:

      • 我有类似的东西,但正如我所说,这种方法存在一些问题。例如,您不能跨行选择。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-31
      • 1970-01-01
      • 1970-01-01
      • 2021-03-04
      • 1970-01-01
      • 2019-04-28
      相关资源
      最近更新 更多