タイトルが大分長くなってしまいましたが…React Native で開発中のチャットアプリでちょっと困ったので対処方法をまとめ。
iOS アプリでチャットの入力欄に改行を含む長文を入力したところ、4行目くらいから縦に伸びた入力欄がキーボードの後ろに隠れてしまうという現象が発生しました。
Android は問題ありませんでしたが、iOS はソフトウェアキーボードが画面を覆うように表示されるせいで、たまにこういったキーボード関連の不具合が発生するんですよね…。
で、こちらは「react-native-controlled-mentions」ライブラリを使って、入力欄をカスタマイズしていたのが原因でした。
チャットページを実装する際に使っている「react-native-gifted-chat」ライブラリの標準の入力欄では、その辺りの処理がちゃんと実装されているため、入力欄でいくら改行してもキーボード後ろに隠れることなく入力欄が縦に広がってくれます。
対処方法ですが、react-native-gifted-chat の Composer コンポーネントを参考に、onLayout メソッドを追加したら、改行に合わせて入力欄が縦に広がるようになりました!
Composer コンポーネントの内容は、下記の GitHub のソースからを確認してください。
react-native-gifted-chat/Composer.tsx at master · FaridSafi/react-native-gifted-chat
https://github.com/FaridSafi/react-native-gifted-chat/blob/master/src/Composer.tsx
81~98行目の onLayout 関数をほぼそのまま転載します。
で、実際にアプリで記述したコードが下記のとおりです。
renderComposer(props) {
const renderMentionSuggestions = renderSuggestions(this.state.members);
const onLayout = (e) => {
if (Platform.OS === 'ios') {
const { layout } = e.nativeEvent
if (!layout) { return }
if (!this.layout || (this.layout && (this.layout.width !== layout.width || this.layout.height !== layout.height))) {
this.layout = layout
if (this.layout && props.onInputSizeChanged) {
props.onInputSizeChanged(this.layout)
}
}
}
}
return (<MentionInput
value={this.state.text}
onChange={text => this.setState({ text: text })}
partTypes={[{
trigger: '@',
renderSuggestions: renderMentionSuggestions,
textStyle: { fontWeight: 'bold', color: '#608CDB' },
isInsertSpaceAfterMention: true,
}]}
onLayout={onLayout}
placeholder={props.placeholder} />);
}
react-native-gifted-chat では、renderComposer という props で入力欄のカスタマイズができるのですが、そちらに上記の内容を記述しています。
追加したのは 3~14 行目の onLayout 関数と、24行目の onLayout で関数を指定しているところの 2か所です。
それ以外は特に変更はしていません。
で、上記を追加して実際に実行してみたところ、意図した通りに動作しました!
なお、Android でも動作しないこともないのですが、入力欄上部の線の上に余白が出来てしまって、ちょっとデザイン的に微妙だったので、iOS の時のみ動作するように指定しています。
以上、React Native の「react-native-gifted-chat」ライブラリと「react-native-controlled-mentions」ライブラリを同時に実装した時に、入力欄がキーボードの後ろに隠れる時の対処方法についてでした。
ご参考になれば幸いです。