ReactNativeでActionSheetを実装する - その②

この前書いたActionSheetの記事書いたけど、特定の状況下だと使えないじゃん!ってなることに気づいた

rskull.hateblo.jp

駄目だった理由

iOSはネイティブの機能を使ってるのでどこで呼び出しても起動するけど

Androidはネイティブの機能ではなく、モーダルっぽいのをRN側で実装されてるので

ヘッダーのアイコンを押したときに起動する、みたいなことをすると

モーダルの位置が正しく計算されず、変なところに表示されたりする。

@expo/react-native-action-sheet

<ActionSheetProvider>
  <ActionSheet />
</ActionSheetProvider>

このコンポーネント自身がActionSheetを起動するためのボタンを持っているのと

Androidではポップアップを持っているので、置き場所によって正常な表示ができないことがある

駄目じゃん…

起動するためのボタンと、ポップアップのコンポーネントは場所を分けたい

近いことをしてたのがコレ

https://github.com/beefe/react-native-actionsheet

<ActionSheet
  ref={o => this.ActionSheet = o}     
/>
showActionSheet() {
  this.ActionSheet.show()
}

自身の ref を渡して起動する

コレだとトリガーを好きなところにおけるけど、Android側のUIが完全にiOSで好みじゃない

結局いいかんじだったやつ

github.com

Androidはネイティブに組み込む必要あってちょっとめんどくさいけど

RNの最新バージョンでも動作してたし大丈夫そう

何がいいってネイティブ実装だし、完全に ActionSheetIOSAPIと一緒なところが良い

どこでも呼び出せて、UIもAndroidに合ったものになってる

インストー

READMEの通り

$ npm install @yfuks/react-native-action-sheet@latest --save
$ react-native link @yfuks/react-native-action-sheet

あとはビルドして終わり

使い方は ActionSheetIOS と同じ

import ActionSheet from '@yfuks/react-native-action-sheet';

...

onOpenActionSheet() {
  const options = ['Delete', 'Save', 'Cancel'];
  const destructiveButtonIndex = 0;
  const cancelButtonIndex = 2;
  ActionSheet.showActionSheetWithOptions({
    options,
    destructiveButtonIndex,
    cancelButtonIndex
  },
  buttonIndex => {
    console.log(buttonIndex)
  })
}

デモ

iOS

f:id:rskull:20170704015625g:plain

Android

f:id:rskull:20170704015649g:plain

満足