#はじめに
こんにちは。今週もReact Native開発のノウハウを投稿させていただきます。
Webページに入力欄を作るとき、TextInput
がよく使われています。入力された文字に応じて、TextInput
のサイズを調整したい、という仕様もよくあるのですが、React Nativeでそれを実現するのは思ったより難しい、と私が気づいています。
ちなみに、React Native PaperにもTextInput
がありますが、スタイルをつけているため、カスタマイズが必要な場合、React NativeのTextInput
のほうが使いやすいと考えております。
調べたところ、TextInput
のpropsにonContentSizeChange
を設定したら、高さの自動調整ができるけれど、デメリットが二つあります。
-
onContentSizeChange
では、改行する時発火されるが、行を削除する時発火されない、というバグがある - 高さが改行に応じて変更されるが、広さの変更ができない
となると、onContentSizeChange
では希望に応えられないときが多いではないかと思っております。ほかに良い方法を考えなければならないですね。
#結論は最初に出す
TextInput
の後ろにText
を重ねていれば、自動調整ができるようになります。
もちろん、Text
コンテンツの末尾にZero-width-spaceを忘れないように。
#解決策
「Talk is cheap」、とにかくソースコードを見てみましょう。
// ...
<View>
<Text style={{fontSize: 18}}>
{message}​
</Text>
<TextInput
style={styles.msgInput}
placeholder={''}
onChangeText={text => setMessage(text)}
value={message}
multiline={true}
numberOfLines={1}
/>
</View>
// ...
const styles = StyleSheet.create({
msgInput: {
position: 'absolute',
top: 0,
left: 0,
fontSize: 18,
width: '100%',
height: '100%',
overflow: 'hidden'
}
});
ご覧の通り、TextInput
に文字を入力したら、その後ろのText
にも表示されます。こうして、TextInput
のサイズもText
と同じようになります。そして、Text
のサイズは中に入れている文字次第のため、したがってTextInput
のサイズも入力した文字に応じて自動調整ができるようになります。
###Zero-width-spaceについて
Text
コンテンツの末尾に、​
をつけているのですが、これはいったい何でしょうか、と疑問を持っている方もいらっしゃると思いますね。
これはzero-width-spaceというものです。つまり、広さが0の文字のことです。
では、zero-width-spaceは何のためにここに入れているのでしょうか?
Zero-width-spaceをつけるのは、改行を対応するためです。
この文字をつけない場合、どうなるか見てみましょう。
ご覧の通り、改行しても、何らかの文字を入力しない限り、高さが変更されなかったです。
Zero-width-spaceをつけましょう。
Zero-width-spaceの広さがゼロですが、一つの文字として高さがあります。そのため、改行したらText
の高さも変更されます。
こうして、入力文字に応じてTextInput
のサイズを調整することができます。
#最後に
この記事はあくまでも私個人(初心者として)の経験です。間違っているところ、もっと良い方法がございましたら、ぜひ教えてください。
#参考資料
https://github.com/necolas/react-native-web/issues/2160
https://www.yuzutalk.net/ ←このサイトは資料ではないけれど、同じくText
とTextInput
を重ねていて、私にヒントを与えました