Author: T.Takaku

  • React Nativeで要素を上下左右に中央寄せする方法

    React Nativeで要素を上下左右に中央寄せする方法

    React Nativeアプリのマークアップにおいても、要素を上下左右に中央寄せにする場合、もちろんスタイルシートによって配置する。この点はWebアプリと変わらない。 しかしReact Nativeのスタイル適用の特徴は、JavaScript記法であること、および梱包要素のボックスモデルのdisplay値はFlexboxであることだろう。 まず「JavaScript記法であること」においては、CSSプロパティ名の単語の先頭を大文字にしなければならない。font-sizeはfontSizeと書く。いわゆるキャメルケースと呼ばれる記法のことである。 そして「ボックスモデルのdisplay値がFlexboxであること」においては、それほど弊害もなくいつも通りのCSSの知識が役立つことだろう。しかしflex-directionのデフォルト値がcolumnである点がややこしい。 このエントリーでは、React Nativeの記法で要素を上下左右に中央揃えする方法を紹介したい。 テキストを上下左右に中央寄せ ここでは<SafeAreaView />に対して、3つのスタイルを適用している。 まずflex: 1,。これは要素サイズをスクリーン縦横幅いっぱいにしている。この指定がなければ、内包要素の高さを保持することになる。たとえば<SafeAreaView />が空要素であるならば、高さ0pxということだ。 つづいてalignItems: ‘center’,では、横方向に対して中央寄せをしている。そしてjustifyContent: ‘center’,が縦方向だ。 お気づきだろう。Flexboxの主軸の向きが縦軸時の指定であると。そう。WebアプリにおけるCSSだとデフォルトの主軸は、alignItemsは縦方向で、justifyContentは横方向だった。そしてflex-direction: column;として縦軸にするとalignItemsが横方向で、justifyContentが縦方向の指定に変化することを思い出せる。 このようにReact Nativeの梱包要素のボックスモデルのdisplay値はFlexboxであり、デフォルトで縦軸になっているのである。 すこしややこしいが、そのようなものだと覚えてもらえると助かる。 画像を上下左右に中央寄せ 画像を上下左右に中央寄せする程度のことは、前述の「テキストを上下左右中央寄せ」の記述で実現できることだろう。だけれど、もし上記ソースコードの<SafeAreaView />に画像以外の内包要素が存在していて、それらはいずれも左寄せで、画像はかぶさる具合に中央寄せするなんてときは、梱包要素で中央寄せ指定ができない。 そこで画像にのみ中央寄せを施すわけだ。内約はposition: ‘absolute’;で、親要素を基準にしたtop: ‘50%’, left: ‘50%’,の相対位置に配置する。そしてtransformプロパティのtranslateXとtranslateYでネガティブポジションすれば、果たして中央寄せができる。 もし画像の裏にタップしたいコンテンツやスクロールしなければならないような場合は、<Image />のpointerEvents propsにnoneを与えればタッチイベントが透き通るはずだ。 まとめ React Nativeで要素を上下左右に中央寄せする方法の紹介だった。 梱包要素に対して適用する方法と固有要素に対して適用する方法をご覧いただいたが、いずれの方法も親要素ありきであることは覚えておきたい。そもそも親要素に高さがなければ、上下中央にはならない。したがってflex: 1;としてスクリーンサイズに吸着させたり、 としたりする工夫が必要だ。 このエントリーが、あなたのクリエイティビティを刺激するものであると期待したい。

  • React NativeでWebViewを使わずHTMLをレンダリングする「react-native-render-html」の紹介

    React NativeでWebViewを使わずHTMLをレンダリングする「react-native-render-html」の紹介

    React Nativeアプリ開発でinnerHTML風な対応が要求された。APIの返り値にHTMLタグが含まれているデータをレンダリングするというものだ。 賢明なあなたにおかれては、<WebView/>を使えばいいじゃん!と思ったに違いない。 そう。そのとおりでWebViewによってHTMLタグを含んだ値をレンダリングすることが可能だ。しかし何かしらのイベントでHTMLタグに付与された属性値を参照する、という処理に悩まされてしまった次第である。 ひとしきりgithubやjs.coachを回遊して見つけたのが「react-native-render-html」だ。 このエントリーでは、HTMLデータを解釈して適当なネイティブビューにレンダリングする「react-native-render-html」を紹介したい。 react-native-render-htmlについて react-native-render-htmlは、HTMLタグを含む文字列値をWebViewを介さず100%ネイティブビューにレンダリングするReact Nativeコンポーネントだ。ネイティブビュー要素は、それぞれ適当なスタイルが当てられる。Normalize.cssが適用されているような状態を思い出してもらうと相違が少ないはずだ。 【react-native-render-html】https://github.com/archriss/react-native-render-html#creating-custom-renderers 特徴 WebViewじゃない HTMLを100%ネイティブビューにする ネイティブビュー要素はあらかじめスタイルが適用されている スタイルをカスタマイズできる HTMLタグ個別にカスタマイズできる 導入 Expo環境下で開発をしているならば、つぎのコマンドでもよいだろう。expo installならばバージョンが整合しているものをインストールしてくれる。 デモンストレーション それではもっともシンプルな実装例をご覧いただこう。 ファイル冒頭でreact-native-render-htmlのHTMLコンポーネントをインポートしている。そののhtml propsにhtmlContent定数を与えている。定数にはHTMLタグで構成された文字列値が格納されている。これがレンダリングされた状態が下図である。先に述べたとおりNormalize.css適用時の装いをしているのがわかると思う。 HTML属性値を取得する 先ほどのシンプルな例では、Normalize.css適用時の装いをしていたけれども、それだけという要件は少ないだろうと思う。きっと特定タグになにかしらのイベント処理を施す必要に迫られる。以下の実装例は、<span/>に固有のスタイル適用とonPressイベントハンドラを定義している。 まとめ HTMLデータを解釈して適当なネイティブビューにレンダリングする「react-native-render-html」React Nativeコンポーネントの紹介だった。 実際に案件で使ってみて、innerHTML風に扱うことができる印象を受けた。HTML属性値を取得する項目でやったような実装をWebViewでやっていたら、きっと相当に悩まされていたに違いない。とても有用なReact Nativeコンポーネントではないだろうか。 このエントリーが、あなたのクリエイティビティを刺激するものであると期待したい。

  • 国際宇宙ステーションの飛行位置を得ることができるAPI「ISS Location Now」の使い方

    国際宇宙ステーションの飛行位置を得ることができるAPI「ISS Location Now」の使い方

    国際宇宙ステーションは地上400km上空を飛行する有人施設であることは周知のことだが、秒速約7.7km(時速約27,700km)ものスピードで飛行を続けていて、地球1周を約90分で周りきるとのことだ。驚異のスピードで想像もつかない。 では国際宇宙ステーションが、たったいまどこを飛行しているのか? それはNASAのサイトで見ることができる。「Live Space Station Tracking Map」は、リアルタイムに現在位置が反映され、およその飛行箇所を確認できるコンテンツだが、自身でもこれに類似したコンテンツを作成することができる。 このエントリーでは、国際宇宙ステーションの飛行位置を得ることができるAPI「ISS Location Now」を紹介したい。 使い方 ISS Location Now APIの使い方はいたって簡単。APIのエンドポイントにGETでリクエストするだけで、json形式の値が返ってくる。APIリクエストにおけるAPI key等のセットは不要だ。 URL http://api.open-notify.org/iss-now.json Request Response デモンストレーション それではAPIの座標データを利用して地図上にピン(アイコン)を表示してみよう。以下ソースコードを確認してほしい。 まず<head>内に必要なアセットを読み込む。 用意したものは、地図ライブラリの「leafletjs」とHTTPクライアントの「axios」だ。サンプルではCDNのものを読み込んでいるが、プロジェクト都合に合わせてローカルに配置してもよいだろう。 つづいて<body>内に地図を描画するHTMLタグを配置する。 Google maps apiを利用したことがあるならば、月並みな記述だと思う。<div>にidを付与して後のスクリプトで参照できるようにしている。サンプルではインラインスタイルによるサイズ固定にしているが、レスポンシブに対応させてもよさそうだ。 最後にISS Location Now APIをリクエストして地図に描画するスクリプトを記述する。 このスクリプトは、5秒毎に緯度経度を取得して、その都度、地図座標を更新する処理をしている。 まとめ 国際宇宙ステーションの飛行位置を得ることができるAPI「ISS Location Now」の紹介だった。 サンプルソースコードでは、OpenStreetMapの地図が描画されるが、Googleマップでも同様のことができる。もし余力があればチャレンジしてみてはいかがだろう。 このエントリーが、あなたのクリエイティビティを刺激するものであると期待したい。

  • React Nativeで横スライドするページの作り方

    React Nativeで横スライドするページの作り方

    React NativeのルーターライブラリのReact Navigationやreact-native-router-fluxを使えば、ページ遷移を再現することができる。またタブ切り替えだったり、スタック式に積み重ねるタイプのUIも備えている。しかし横スライドするような表現には向いていないように思う。 実際に構築しようとするならば、スクリーン数に応じてルーターを定義するか、ルーターパスを参照するようなことを思い及ぶ。しかしスライド数が可変だった場合の対応に困るし、都度定義するようだと運用を考慮するとナンセンスだ。 このエントリーでは、横スライドするページの作り方を紹介したい。 はじめに 横スライドするページとは、複数スクリーンにわたって横に遷移している様を表現しているコンテンツだ。たとえばアンケートページや回答ページなどに見られる造りで、スクリーン毎にアクションを起こしてもらうようなシーンに使われる。 作り方 まずはソースコードで確認していこう。 上記は、横スライドするページに関するソースコードだが、見通しが悪くなる記述はすべて削除している。その点、容赦いただきたい。特にスタイルシートは一部を除いて、すべて削除しているから、脳内で良しなに置換しながら眺めてほしい。 さて前述では横スライドのことを「遷移している様」と表現しているが、実際には横スクロールで遷移している様を再現する。そのために必要なのが<FlatList/>だ。 <FlatList/>は、リストをレンダリングするためのUIコンポーネントで、クロスプラットフォームに対応している。 <FlatList/>のdata propsに与えた配列数に応じて、renderItem propsのコンポーネントが複数列レンダリングされる。 レンダリングされた要素には、keyExtractor propsでKeyを付与する。このときインデックス値だけを与えるのは悪手とされているから、なにかしらの文字列を含めると良いだろう。 そしてhorizontal propsによって横並びにする。 scrollEnabled propsにfalseを与えると、スクロールを禁止できる。横スライドするページを表現するには必要な設定だろう。この場合、ボタンの押下によってスライドすることが考えられる。 FlatListコンポーネントのscrollToIndex({index: インデックス値})を実行するとインデックス値の要素がビュー領域にスクロールしてくるものだ。このscrollToIndex()メソッドにアクセスするためref propsで<FlatList/>への参照先を定義しなければならない。 あと、ひと工夫で、renderItem propsでレンダリングされるコンポーネントのトップレベル要素は、コンテンツ量に応じて縦スクロールするように<ScrollView/>などを配置したいところだ。サンプルソースコードの<Content/>は、<ScrollView/>と<SafeAreaView/>をラップしたものだ。 この縦スクロールの配慮で、ひと手間が発生する。たとえば縦長コンテンツの最下部にあるNextボタンで次ページに横スライドして、Prevボタンで前ページに横スライドすると、その時点のスクロールビューは最下部状態のままになっている。これは再読み込みということではないから仕方のないことなのだが、前ページに戻って最下部状態というのは、いささか不自然感が否めない。 これに対処するため、scrollToPosition(0, 0, false)の実行でカレントページを最上部にスクロールさせたうえで、横スクロールを実施したというわけだ。このscrollToPosition()メソッドにアクセスするため<Content/>にもref propsで参照先を定義している。 まとめ 横スライドするページの作り方の紹介だった。 scrollToIndex()について伝えたとおりインデックス値を与えれば、対象インデックスページにスライドする。この横スライドには、デフォルトでアニメーションが付与されている。アニメーションを廃止して俊敏にスライドしたい場合には、scrollToIndex({animated:false,index:0})って具合にanimatedプロパティが設けられている。スライド感を無くしたいときに使ってみても良さそうだ。 このエントリーが、あなたのクリエイティビティを刺激するものであると期待したい。

  • React Native + Chart.jsでアプリ画面にレーダーチャートを表示する

    React Native + Chart.jsでアプリ画面にレーダーチャートを表示する

    React Nativeにおいてもグラフ描画ライブラリはいくつか存在するが、必ずしも要求する図表モードがなかったり、グラフのUIが要件に沿わなかったり、と障害に遭遇する。あなたも「Webアプリならば、あれを使うのに!」とか「あのライブラリのReact Native版はないの?」とか思い及ぶシーンは少なくないかもしれない。 わたしの体験では、レーダーチャートのUIが要件にマッチするものが見当たらず、Webアプリ制作で馴染みのあるChart.jsを使ったということがあった。 このエントリーでは、React Native + Chart.jsでグラフ描画する方法を共有したい。 はじめに React NativeのコンポーネントにChart.jsでグラフ描画するに際して、React Native用のものを探すと「react-native-chartjs」なるものを見つけることができた。 これはReact NativeのWebViewコンポーネントを介して、HTMLのcanvasにグラフを描画するコンポーネントだ。これがもっとも簡単な方法と思われた。 ところが今日時点のバージョンだと、非推奨のライフサイクルメソッド(componentWillMount)使用による警告が発せられて、グラフ描画ができなかった。解消する手立てを講じるのも面倒くさく。 非常に残念に思いながら、自ら<WebView/>で実装することを決めた。 グラフ描画する このサンプルは、以下のようなレーダーチャート描画を想定している。 index.html Chart.jsのグラフ描画に必要なHTMLファイルを外部ファイルで用意する。当該ソースコードは、Webサイト制作の経験があるならば説明不要だろうと思う。CDNにホスティングされているChart.jsを読み込んでいる。 ChartScreen.js 当該ファイルは、React Nativeの任意のコンポーネントだ。ファイル名に意味はなく、開発都合に合わせて命名してもらって構わない。 <WebView/>のsource propsにHTMLを渡すのだが、injectedJavaScript propsに渡すJavaScript同様にテンプレートリテラル記法にすれば、プラットフォーム間の相違がなくスムーズに済む。しかし可読性を損なってしまうことから外部ファイル化を検討してみた。 HTMLの外部ファイル化に際して、すこし工夫が必要になる。iOSとAndroidでファイル参照に差異があるそうで、たとえばiOSならば<Image/>のsource propsのようにrequire()で認識するが、Androidは{uri: ファイルパス}の形式で定義しなければならないわけだ。しかもプロジェクトルートからではなく、file://プロトコルを含むデバイス上のローカルファイルを指す必要がある。 もしExpo環境下ならば、Asset APIを使うとローカルファイル参照は容易い。Asset.fromModule(assetHtml);の具合に、require()で参照した値を渡すとlocalUriプロパティにローカルファイルパスが反映する。あとはプラットフォームを判定して、WebViewに渡すだけだ。 外部ファイルを読み込むことを配慮して、インジケータを表示してもよいかもしれない。これは<WebView/>のstartInLoadingState propsが担ってくれる。 まとめ React Native + Chart.jsでグラフ描画する方法の共有だった。 グラフ描画に限らずWebコンテンツを必要とするシーンならば、<WebView/>に外部HTMLファイル読み込みの手法は役立つかもしれない。サンプルとして示すためHTMLは非常に簡素なものだったが、もっとしっかりコーディングすることにはなりそうだ。 このエントリーが、あなたのクリエイティビティを刺激するものであると期待したい。

  • React hooksのuseStateにコールバックをセットするには

    React hooksのuseStateにコールバックをセットするには

    React 16.8でReact hooksが導入されて久しい。 いまとなってはステートレスコンポーネントがReactコンポーネント作成のデファクトスタンダードになっている。すでにいくつかのクラスコンポーネントのライフサイクルは非推奨になっているものもある。 React hooksの導入に際して、まず接点があるであろうメソッドはuseState()だろうか。これはthis.setState() として状態を更新していたもののhook版と認識してもらえればよい。馴染みのあるthis.setState()とReact hooksのuseState()は、使いどころこそはおよそ同じであるが、this.setState()にできて、useState()にできないこともある。 それはコールバックの定義だ。 このエントリーでは、ステートレスコンポーネントにおける状態更新のコールバックについて共有したい。 まず、クラスコンポーネントは? ステートレスコンポーネントにおけるコールバックを示す前に、クラスコンポーネントの例を確認してもらおう。クラスコンポーネントであるから、もちろんthis.setState()だ。 this.setState()の第一引数がステートオブジェクト、第二引数がコールバック関数だ。この例では、無名関数を定義しているが、任意の関数をセットできる。 では、ステートレスコンポーネントだと? 前述したとおり、useState()だとコールバックを定義できない。useState()は、状態値の定義と状態を更新するための関数を分割代入するだけのもので、this.setState()のようにコールバックを定義する機能は備わっていない。ではステートレスコンポーネントで状態が更新されたことを捕捉するにはどうしたらよいのだろう。 ステートレスコンポーネントの場合は、React hooksのuseEffect()を使う。 useEffect()は、ライフサイクルのcomponentDidMountやcomponentDidUpdate、componentWillUnmountに類似したものと認識してもらえればよい。 componentDidUpdateライフサイクルでは、現在のステートと更新されるステートを比較して何らかの処理を実行するような場合に使っていた。useState()でもこれを再現させれば良さそうだ。 useEffect()の第二引数に[isVisible]を渡している。これは現在のステートと更新されるステートを比較して、もし同値であればuseEffect()の第一引数の無名関数をスキップするというものだ。 果たして、ステート更新のコールバックを再現することができた。 まとめ ステートレスコンポーネントにおける状態更新のコールバックに関する共有だった。 useEffect()の第二引数に渡したステート変数を観測することで、コールバック関数を再現したわけだが、このソースコードの例では、コンポーネントがマウントされたタイミングでも実行されてしまうはずだ。そのようなときは無名関数内でステート値を厳密にチェックするようにしてほしい。 このたび言及した方法のほかに「use-state-with-callback」なるパッケージがあるようで、これでもコールバックができるらしい。わたしは試していないが、期待した機能は保有している様子だ。トライしてみても良いだろう。

  • アンカーリンクの遷移先が隠れる…。追従ヘッダーの重なりを回避するCSS

    アンカーリンクの遷移先が隠れる…。追従ヘッダーの重なりを回避するCSS

    サイト制作で縦長デザインを採用するとき、動線の確保を配慮しなければならない。スクロールすることで現在地を見失い、迷子になることが考えられる。いまどこにいて何を閲覧しているか分からなくなるというものだ。 そのような対策のひとつに、ヘッダーをウインドウ上部に固定配置して、いかなるスクロール位置にいてもメニューにアクセスできるようする、というものがある。このメニューをアンカーリンクにすることでユーザビリティに配慮したサイトを見たことがあるかもしれない。たとえば、ブログなど文章系コンテンツにしても目次を設けて対象セクションに遷移するものもある。 このように縦長サイトにおいて、追従ヘッダーとアンカーリンクは比較的セットで実装されることがあるわけだが、ヘッダーが固定されていることでアンカーリンクの遷移先が隠れてしまう問題に遭遇する。 このエントリーでは、アンカーリンク遷移先に追従ヘッダーが重ならないようにするCSSを紹介したい。 問題 解決 See the Pen Untitled by Takuya Takaku (@takuya-takaku) on CodePen. 追従ヘッダーのメニューがアンカーリンクになっている。アンカーリンクは各種見出しがターゲットで、クリックするとページ内遷移する。 見出しに追従ヘッダーが重なることなく表示されればOKだ。 ここで注目すべきは、CSSのscroll-padding-topプロパティだ。scroll-padding-topプロパティは、スクロールポート上部にオフセット値を付与できる。スクロールポートとは、スクロールバーが発生している領域だと認識してもらえば差し支えない。 サンプルソースコードではscroll-padding-top: 60px;として、追従ヘッダーの高さをオフセットするようにしている。 まとめ アンカーリンク遷移先に追従ヘッダーが重ならないようにするCSSの紹介だった。 元来、アンカーリンク遷移先の要素に上余白を与えて擬似的にオフセットを作っていたことを考えると違和感なく理解できるものだと思う。ただしIE,Edgeに関しては、部分的なサポートに留まっている。要件によっては、しっかりサポート状況を確認してもらいたい。 このエントリーが、あなたのクリエイティビティを刺激するものであると期待したい。

  • NativeBaseのDatePickerコンポーネントの日付表記をフォーマットする方法

    NativeBaseのDatePickerコンポーネントの日付表記をフォーマットする方法

    React Nativeによるアプリ開発において、UIコンポーネントの導入は珍しいものではない。むしろポピュラーとまで感じるほどではないだろうか。なかでもNativeBaseが、もっとも高名なUIコンポーネントだといえる。 そんなNativeBaseのコンポーネント群に日付選択を手助けするものがある。DatePickerだ。 NativeBaseのDatePickerコンポーネントは、IOSとAndroidのプラットフォームを判定して専用のDatePickerをレンダリングしてくれる。IOSならばDatePickerIOSコンポーネントで、AndroidならばDatePickerAndroid APIが呼び出されるわけだ。 NativeBaseのDatePickerコンポーネントの実装は、公式ドキュメントのとおり記述すれば、なんの問題もなく配置できることだろう。ところがDatePickerコンポーネントの日付表記が英語圏のものと気づいて戸惑うかもしれない。 このエントリーでは、NativeBaseのDatePickerコンポーネントの日付表記を日本語形式フォーマットする方法を紹介したい。 解決法 さっそく解決法を示そう。サンプルソースコードとして公式ドキュメントのものを拝借して、そこに追記している。では下記ソースコードを確認してほしい。 追記した箇所は、2行だ。 まずソースコード上部にimport moment from ‘moment’;としてMoment.jsをインポートしている。Moment.jsは日付時刻操作ライブラリで、フォーマットするときなどに使う。 つづいて<DatePicker />にformatChosenDate={ date => moment(date).format(‘YYYY年MM月DD日’) }としてformatChosenDate propsを用意している。これは日付フォーマット用のpropsで、DatePickerコンポーネント内で参照されている。もしformatChosenDate propsが存在しなければ英語圏の日付表記が適用される仕組みだったわけだ。 まとめ NativeBaseのDatePickerコンポーネントの日付表記を日本語形式にフォーマットする方法の紹介だった。 そもそも公式ドキュメントにformatChosenDate propsの記述がない。DatePickerコンポーネントの実ソースコードを眺めていて発見したものだ。 もしまだ実装の時でないならば、頭の片隅に入れておいてほしい。 このエントリーが、あなたのクリエイティビティを刺激するものであると期待したい。

  • [React Native] フォントサイズが異なる文字列を下揃えする方法

    [React Native] フォントサイズが異なる文字列を下揃えする方法

    Flexboxは、Webサイトにおけるコーディングではおなじみのレイアウトモデルで、縦軸や横軸の単一軸に整列させるものだ。React Nativeのレイアウトでも、Flexbox概念を用いて成形する。 そしてレイアウト用コンポーネントには、あらかじめFlexboxが定義された状態になっている。HTMLにあたるブロックレベルエレメントやインラインレベルエレメントという概念はなく、displayプロパティが存在しない。そして、すこし特徴を感じるのが、レイアウト用コンポーネントは、縦軸に整列するflex-direction: column;が与えられている点だろう。 さて、以上のことを踏まえて主題の文字列を下揃えにする方法であるが、この程度のことではまってしまったので自身の備忘録かたがた、それを共有したい。 やりたいこと 表現すべきレイアウトは、文字サイズの異なる文字列を下揃えにするものだ。下辺を揃え、上辺が凹凸になる状態を表現したい。 React Nativeのレイアウトモデルは、Flexboxだった。しかも初期時は、縦軸に整列するflex-direction: column;だった。 したがって、まずやることは横軸にすること。flex-direction: row;で横に整列させる。続いて縦軸に関する指定を担うalign-items: baseline;で、文字列をベースラインに沿うようにする。 しかし… しかしAndroidで、下揃えにならない。 左がAndroidで、右がiPhoneだ。下揃えされていないことがわかる。見た感じ行の高さによるもののようだから、lineHeightやtextAlignVerticalを試みたが見込めなかった。 解決法 やむを得ず<Text/>内に<Text/>を展開することで着地することにした。 HTMLコーディングにおける<p/>内の<span/>のような装いになっている。これならば親<Text/>の行の高さは、文字サイズが大きいものと等しくなり、ベースラインに沿うことになったわけだ。 このあたりの仕様は、Webブラウザそのままで安心できる。 まとめ フォントサイズが異なる文字列を下揃えする方法の紹介だった。 <Text/>内に<Text/>を展開することで、当該件は着地することにしたが、それでもまだ問題がある。 それは<Text/>で余白を調整できない点だろう。<p/>内の<span/>では、span要素でも余白を与えることができたため、そのようなことで悩むことはなかったのだが、React Nativeでは工夫が必要らしい。 このエントリーが、あなたのクリエイティビティを刺激するものであると期待したい。

  • [React Native] 吹き出しUIの作り方とコーディングサンプル

    [React Native] 吹き出しUIの作り方とコーディングサンプル

    Webアプリで吹き出しUIをコーディングするには、CSSの疑似要素を工夫して三角形を形成する。ところがReact Nativeでは疑似要素をサポートしていない。というのもReact Nativeのスタイルの適用方法は、オブジェクト形式で定義しなければならないからだ。 そもそもネイティブアプリ作成におけるレイアウトで、疑似要素っぽいことを求めるシーンがあるのか知らないが、React NativeのCSS適用方式では、それを再現することができない。 それでもデザイン要件で、吹き出しUIをコーディングしなければならないこともある。 このエントリーでは、React Nativeコンポーネントに吹き出しUIをつくる方法と、そのコーディングサンプルを紹介したい。 React Nativeにおける疑似要素 まず疑似要素について言及しておこう。CSSの疑似要素とは、ターゲット要素に対して擬似的に仮想の要素を配し、スタイル適用を可能にしている。たとえば::beforeならば、ターゲット要素の先頭子要素として要素が挿入される。::afterならば、ターゲット要素の末尾子要素として要素が挿入される。 このように擬似要素として定められた特定の場所に仮想の要素が挿入され、さまざまな装飾に活用されている。 ところがすでに述べたとおり、React Nativeのスタイル適用方法では、これをサポートしていない。疑似要素はサポートしていないのだが、再現はできる。 疑似でなければよいのだ。 吹き出し三角形のしくみ React Nativeで吹き出しUIのコーディングサンプルを示す前に、吹き出しUIたらしめる三角形オブジェクトのCSSを確認しておきたい。 ここでポイントとなるプロパティは、width,height,borderが三角形を形成している。ボックスモデルの概念だとcontent領域の外側にpadding領域があって、border領域、margin領域をもつ。 上記のCSSを見ると、width,heightは0pxで、borderは上、右、左辺が10pxになっている。つまりcontent領域は潰して、border領域でサイズを得ていることがわかる。 上辺のボーダー幅が10px、左右辺ともにボーダー幅が10px、色を透明にすることで、上辺ボーダーだけ残って三角形に見えるという理屈だ。この場合の疑似要素サイズは、横幅20px、縦幅10pxになる。下辺ボーダーを定義していないため、上辺ボーダー幅しか保持せず縦幅は10pxというわけだ。 吹き出しUIのコーディングサンプル それでは本題の吹き出しUIのコーディングサンプルをご覧いただこう。 上向き吹き出し 右向き吹き出し 下向き吹き出し 左向き吹き出し まとめ React Nativeコンポーネントに吹き出しUIをつくる方法と、そのコーディングサンプルの紹介だった。 Webコンテンツのコーディングとの相違は、疑似要素ではなく空要素にスタイルを当てるという一点くらいなもので、難しさはないはずだ。三角形を形成するアプローチはCSSコーディングそのものでボーダーを工夫して再現する。 つまりそのアレンジ方法もWeb用エントリーのものから得ることができるということだ。「CSS 吹き出し」などで検索すると、それらしい情報が得られるはずだ。 このエントリーが、あなたのクリエイティビティを刺激するものであると期待したい。