Подтвердить что ты не робот

Rich ReactNative TextInput

Любой способ создать "богатый" TextInput in React Native? Возможно, это не полный размытый wysiwyg, но, возможно, просто измените цвет текста различных фрагментов текста; как функция @mention в Twitter или Facebook.

4b9b3361

Ответ 1

Решение состоит в том, что вы можете использовать элементы <Text> как дочерние элементы в <TextInput> следующим образом:

<TextInput>
    whoa no way <Text style={{color:'red'}}>rawr</Text>
</TextInput>

Ответ 2

Для достижения этого поведения вам придется использовать регулярное выражение. Кто-то уже создал пакет для просмотра react-native-parsed-text

Эта библиотека позволяет анализировать текст и извлекать детали с использованием RegExp или предопределенных шаблонов. В настоящее время существует 3 предопределенных типа: URL, телефон и электронная почта.

Пример из их github

<ParsedText
          style={styles.text}
          parse={
            [
              {type: 'url',                       style: styles.url, onPress: this.handleUrlPress},
              {type: 'phone',                     style: styles.phone, onPress: this.handlePhonePress},
              {type: 'email',                     style: styles.email, onPress: this.handleEmailPress},
              {pattern: /Bob|David/,              style: styles.name, onPress: this.handleNamePress},
              {pattern: /\[(@[^:]+):([^\]]+)\]/i, style: styles.username, onPress: this.handleNamePress, renderText: this.renderText},
              {pattern: /42/,                     style: styles.magicNumber},
              {pattern: /#(\w+)/,                 style: styles.hashTag},
            ]
          }
        >
          Hello this is an example of the ParsedText, links like http://www.google.com or http://www.facebook.com are clickable and phone number 444-555-6666 can call too.
          But you can also do more with this package, for example Bob will change style and David too. [email protected]
          And the magic number is 42!
          #react #react-native
</ParsedText>

Ответ 3

Взгляните на TokenizedTextExample из интерактивных документов. Я думаю, это приблизит вас к тому, что вы хотите сделать. Соответствующий код следует:

class TokenizedTextExample extends React.Component {
  state: any;

  constructor(props) {
    super(props);
    this.state = {text: 'Hello #World'};
  }
  render() {

    //define delimiter
    let delimiter = /\s+/;

    //split string
    let _text = this.state.text;
    let token, index, parts = [];
    while (_text) {
      delimiter.lastIndex = 0;
      token = delimiter.exec(_text);
      if (token === null) {
        break;
      }
      index = token.index;
      if (token[0].length === 0) {
        index = 1;
      }
      parts.push(_text.substr(0, index));
      parts.push(token[0]);
      index = index + token[0].length;
      _text = _text.slice(index);
    }
    parts.push(_text);

    //highlight hashtags
    parts = parts.map((text) => {
      if (/^#/.test(text)) {
        return <Text key={text} style={styles.hashtag}>{text}</Text>;
      } else {
        return text;
      }
    });

    return (
      <View>
        <TextInput
          multiline={true}
          style={styles.multiline}
          onChangeText={(text) => {
            this.setState({text});
          }}>
          <Text>{parts}</Text>
        </TextInput>
      </View>
    );
  }
}

Ответ 4

Этот вопрос был задан некоторое время назад, но я думаю, что мой ответ может помочь другим людям, ищущим, как закрасить часть @mention строки. Я не уверен, является ли способ, которым я это сделал, "чистый" или "реагирующий", но вот как я это сделал: я беру введенную строку и разделяю ее с пустым пространством в качестве разделителя. Затем я перебираю массив и, если текущий элемент совпадает с шаблоном @subject/@user, он заменяется тегом Text с примененными стилями; остальное вернуть товар. В конце я отображаю массив inputText (содержащий строки и элементы jsx) внутри элемента TextInput. Надеюсь это поможет!

render() {
let inputText = this.state.content;
if (inputText){
  inputText = inputText.split(/(\s)/g).map((item, i) => {
    if (/@[a-zA-Z0-9]+/g.test(item)){
      return <Text key={i} style={{color: 'green'}}>{item}</Text>;
    } 
    return item;
  })
return <TextInput>{inputText}</TextInput>

Result