最近Expoでアプリ書いてるのに使ったTipsなど
React Native Advent Calendar 2018 - 17日目の記事です
最近Expoでアプリを書いているので、そこで使った小ネタを紹介
独自実装したモーダルの動き#reactnative #expo pic.twitter.com/bBKOtMKdvk
— .あーる (@DotEarl) December 3, 2018
画面全体を覆うスタイルを定義したい時
Stylesheet.absoluteFillObject
画面全体をピッタリ覆うスタイルを付けたい時に使えます
export default class App extends React.Component { render() { return ( <View style={styles.container}> <TouchableOpacity> <Text>Button</Text> </TouchableOpacity> <View style={styles.fill} /> </View> ); } } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center' }, fill: { // 縦横いっぱいでabsoluteなViewのスタイルを設定 ...StyleSheet.absoluteFillObject, // わかりやすく色を付けてる backgroundColor: 'rgba(255, 0, 0, 0.2)' } });
赤くなってる範囲が <View />
に absoluteFillObject
を設定した範囲です
いつ使うのか? 例えば環境に影響されない(どこに置いても成り立つ)フローティングボタンを作りたい場合などに使えます
被さったViewのタッチ判定を無効化する
当たり前ですが、このままだと赤いマスクの裏の画面が全く触れなくなってしまいます
そんな時は <View />
に pointerEvents="box-none"
を設定します
<View style={styles.fill} pointerEvents="box-none"> // ... </View>
全面にある赤い <View />
のタップ判定を無効にして、なにもないように振る舞わせることができます
意外と色んなところで使えそう
キーボードの上に「完了」とか付けるやつの実装
これ、よく使うと思います
RNにもともと入ってる InputAccessoryView
コンポーネントで実装はできますが、バギーで使えませんでした
自分で実装したんですが、ここでも pointerEvents="box-none"
が出てきます
スペーサーに外部のライブラリ使ってますが
import React from 'react'; import { View, ViewProps, StyleSheet } from 'react-native' import KeyboardSpacer from 'react-native-keyboard-spacer'; interface Props extends ViewProps { children: React.ReactNode; } export const InputAccessoryView = ({ children, ...rest }: Props) => ( <View {...rest} pointerEvents="box-none" style={styles.wrap}> {children} <KeyboardSpacer /> </View> ) const styles = StyleSheet.create({ wrap: { ...StyleSheet.absoluteFillObject, justifyContent: 'flex-end', } })
children
がキーボードの上に乗るところです
あとはこのコンポーネントを使って好きに実装します
import React from 'react'; import { View, ViewProps, TouchableOpacity, Text, Keyboard } from 'react-native' import { InputAccessoryView} from './InputAccessoryView' import styled from 'styled-components' const Inner = styled(View)` align-items: flex-end; padding: 12px 16px; background: #f2f2f2; `; const TextButton = styled(TouchableOpacity)` font-weight: bold; color: #15a2ff; `; interface Props extends ViewProps { visible?: boolean; onClosed?: () => void } export const InputAccessory = ({ visible, onClosed, ...rest }: Props) => { if (visible === false) { return null } return ( <InputAccessoryView {...rest}> <Inner> <TextButton onPress={() => { if (onClosed) { onClosed() } Keyboard.dismiss() }} > <Text>完了<Text> </TextButton> </Inner> </InputAccessoryView> ) } Accessory.defaultProps = { visible: true, onClosed: undefined, }
例えばこんな感じ
「完了」ボタンを置いてキーボードが閉じるように実装します
<InputAccessoryView />
はただキーボードの上に乗る要素を作るだけのコンポーネントです
https://gist.github.com/rskull/3fb91f4c19f49d86355987d1c35fbb35
まとめ
かなりざっとな記事ですみません
3ヶ月くらいExpoで開発してる感想は、めっちゃ楽の一言でした
以前素のRNを2年半くらい触ってましたが、ビルドは落ちるし時間かかるしで辛かったです(当方ネイティブ初心者なので...)
プロジェクトごとにアカウントを作って、そのアカウントをメンバーで共有すれば
コマンドでデプロイ後すぐにシェア、確認できるのですごい作業がはかどりました
なんとかリリースまでこぎつけたいですね
以上です。良いお年を