【ワンランク上のPower Apps】 スマホ対応 レスポンシブ レイアウト

# はじめに
こんにちは。ヨウセイです。
Microsoft Power Apps Advent Calendar 2022 カレンダー３が出来ていたので、せっかくなので数日前にやった自社アプリのスマホ用対応について綴ろうかと。カレンダー３の12/23用の記事です。

ワンランク上のおっさんはレスポンシブにアプリ画面を切り替えることができる～～！
ということでまずは、Web版、スマホ版でアプリを作る際のパターンから
※のみさん元気だろうか

# 実装サンプル　
DataverseforTeamsアプリ、軽いレスポンシブ対応にスマホ用画面を追加
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">レスポンシブサンプル <a href="https://t.co/mzswMsB3wD">pic.twitter.com/mzswMsB3wD</a></p>&mdash; ヨウセイ (@youseibubu) <a href="https://twitter.com/youseibubu/status/1605891641272852486?ref_src=twsrc%5Etfw">December 22, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

DataverseforTeamsスマホアプリのみ※上記みずらかったので
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">dataverse for teamsスマホ版 <a href="https://t.co/t7FKJVuDg9">pic.twitter.com/t7FKJVuDg9</a></p>&mdash; ヨウセイ (@youseibubu) <a href="https://twitter.com/youseibubu/status/1605885340702720001?ref_src=twsrc%5Etfw">December 22, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# Web版、スマホ版アプリの作成パターン
アプリ作成時はWeb版（PC/タブレット用）とスマホ版（スマホアプリ用）をどう作るか？作らないかのパターンがいろいろあると思います。
ざっと上げると以下のような感じかと。

<table>
  <thead>
    <tr>
      <th>＃</th><th>パターン</th><th>ポイント</th>
    </tr>
  </thead>
  <tr>
    <td> ① </td><td>Web版のみ作る</td><td>スマホでは横画面で使う。<br>※スマホではあまり利用がない前提</td>
  </tr>
  <tr>
    <td>②</td><td>スマホ版のみ作る</td><td>PCでもスマホ版で使う。タブレットなら縦で<br>※PC／タブレットではあまり利用がない前提</td>
  </tr>
  <tr>
    <td>③</td><td>2種類のアプリを作る</td><td>それぞれのアプリを開いて利用する。</td>
  </tr>
  <tr>
    <td>④</td><td>１アプリで画面を分ける</td><td>画面サイズで判定し画面を切り分ける。<br>※レスポンシブレイアウト前提（Automateでブラウザ種類判定やればレスポンシブでなくても可能かも？）</td>
  </tr>
  <tr>
    <td>⑤</td><td>１アプリで同画面で分ける</td><td>画面サイズで判定し画面内のコントロール全般を調整<br>※レスポンシブレイアウト前提</td>
  </tr>
</table>

# パターンの所感
PC版のみ、スマホ版のみがメインなら1つ作ればOKですね。PC版レイアウトでもスマホで横で使ってもらえればある程度代用はできますし。
PCもスマホも必要となると、③の2つ作るのが手っ取り早いケースが多い気がします。
※M365ライセンス範囲なら問題ないが有償ライセンス版なら2アプリ分ライセンスが発生するのでケースバイケース

⑤のようにレスポンシブ対応して1アプリ同画面で完結させれば、修正時に1か所で済むメリットがあります。が、慣れてないと初動に結構時間がかかってしまうかなと。難易度は一番高いですよね。
通常はデフォが画面フィットの設定なので好きな位置にコントロールを配置すればいいですが、レスポンシブの場合は各所で動的なレイアウト調整が必要になります。
今は水平、垂直コンテナーやアプリの画面レイアウトが使えて、いい具合に配置もできるようにもなっています。これらをうまく使えればスムーズかもですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249807/622ba390-cc8b-923f-f767-085e80b70470.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249807/43f76c47-83bc-a677-89b7-3bae1f74a3c9.png)
この辺の公式情報はこちら。
https://learn.microsoft.com/ja-jp/power-apps/maker/canvas-apps/build-responsive-apps
https://learn.microsoft.com/ja-jp/power-apps/maker/canvas-apps/create-responsive-layout

自分的には③の別アプリで2つ作るか、レスポンシブ対応としても④のサイズによって画面を分けて作るほうが作成時はだいぶ楽かなーというイメージです。軽いレスポンシブ（横幅を動的に伸ばす程度）であれば大したことないですが、Web版とスマホ版を同画面で作るのは結構つらい。（サイズや配置場所、表示非表示切り替えなどいっぱい対応すべきことがあるし、分けたほうが柔軟な対応ができる）

# 実装背景
今回対応したのはDataverseforTeamsで作った自社で使用中の経費精算アプリです。

★DataverseforTeamsはTeams上で使う前提なのでPower Appsスマホアプリでは開けない（なぜかたまに開くが基本使えない認識）んですが、スマホ版Teamsアプリは横表示してくれないんです！なので①のWeb版だけ作ってスマホは横で使って。の方針が取れない。。
元々横幅広げる程度のレスポンシブ対応は入れてましたが、面倒だったのでスマホで開くと「対象外です。PCでやってください。」というラベルのみの画面に遷移させておりました( ´∀｀ )
そのうちに対応してあげようと思い2年ほど経過、、今月領収書の画像アップを一旦スマホで撮影してPCに送ってTeams上でアプリに追加して、、とやってみて、こりゃスマホ版必要だわ！となりました。

もともとレスポンシブ対応と画面切り分けはやっていたので、その流れで今回は、④の「１アプリで画面を分ける」（画面サイズ判定し遷移する画面を切り分ける）方針で、そのままスマホ画面を追加することにしました。

ちなみに今回本機能を追加した自社アプリの概要は以前こちらで紹介しております。

http://www.nsurf.co.jp/archives/1590

# ① レスポンシブ対応設定・画面サイズ判定
+ まずはアプリをレスポンシブ対応にします。
設定＞表示で「画面に合わせて倍率を変更」をオフにします。縦横比も自動でオフになります。
※既定ではオン、縦横比をロックもオンなので、普通に作った場合は自動で画面サイズに拡大縮小してくれるアプリになります。
向きのロックはスマホ、タブレット用の設定です。今回はTeams上で表示のみとなり縦固定なのでどちらでも影響なし。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249807/48d462ca-0dfd-72e6-1f33-1cffcf3b19cf.png)

+ ブレークポイントについて
Appにはブレークポイントが最初から設定されています。カスタムも可能ですが通常はそのままでよいかと。
上記の自動拡大をオフにすると画面のサイズプロパティを使っての判定が可能となります。幅が600以下だとSmallとなります。
今回は最初の画面遷移の判定くらいしか利用してませんが、画面内でブレークポイントに応じたコントロール調整（サイズや表示など切り替える）が可能です。
```
例：　If(App.ActiveScreen.Size = Small,Navigate(mobileScreen))　みたいな感じ
```
・AppのSizeBreakPoints
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249807/5c3cb9f9-1de1-664b-deb2-e1e56e027ada.png)
・ScreenSize 型
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249807/cd8b83ea-2acf-2e96-268a-57aa43ba3f6f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249807/cbbb9b4b-85f0-d7e3-9060-ae589301f670.png)
詳細はこちらを
https://learn.microsoft.com/ja-jp/power-apps/maker/canvas-apps/create-responsive-layout#screen-sizes-and-breakpoints

+ 画面の幅、高さについて
参考のリンク先には画面の幅、高さにはDesignWidth、DesignHeightが設定とあり、たしかに前はそうだった記憶ですがいま見ると使われれてないようです。
Max(App.Width, App.MinScreenWidth) となり、アプリの最小（320）か画面サイズの大きなほうという感じですね。レスポンシブでない場合は作成時のレイアウトに沿ったサイズ内容になります（横：16：9なら1366とか）
・スクリーンのWitdhとHeightの既定の設定値
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249807/b40af9cc-16d0-2bf6-e8d2-6bddc5102a97.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249807/9c27a4f6-445a-268a-d3c7-4efc179f119f.png)

# ② 画面判定・切り分け（切り分け用スタート画面の追加）
次にブラウザのサイズに応じて遷移先を切り替えるのですが、
まずApp.OnStart内では「App.ActiveScreen.Size = Small」での判定が取れませんでした。画面がまだ決まってない段階だからでしょう。
また最近ではOnStartでのNavigateは廃止予定でStartScreenで画面切り分けを推奨されてますが、App.OnStart内で初期設定で各種変数設定もしていてその辺を使っての切り分けもあり、StartScreenでは変数使えないのでこれもやめました。


そもそもApp.OnStartはいまやオンにしないと機能しないようになっているので、
初期表示用の画面を用意してその中で初期化、画面判定の処理を追加することで対応しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249807/efaf4c30-91aa-6501-2cf4-a3cdcc176df9.png)
※もともとはWeb版画面にNavigateを書いてモバイルだったら非対応画面に飛ばしてましたが、一瞬見えるのもいやだったので今回の改修に合わせて初期表示用の画面を追加しました


+ 初期画面（ScreenLoading）の追加
　ScreenLoading画面として一番上に画面を追加。ヘッダーとローディングのみを表示
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249807/3dffcc41-71e3-258a-a37c-57220169aef1.png)

+ OnVisibleの処理
★OnVisible内でのNavigateも使えません！
次にOnVisibleに初期化処理を書くのですが、そのままNavigateが書けません。以下のようなエラーとなります。ので、非表示ボタンを用意してSelectさせてNavigateを動かす技を使って実装しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249807/5db9bfd2-c76d-116d-ed42-f8a3279d2d87.png)
OnStartに書いてあった初期化の処理と、以下の画面サイズ判定を追加し、その後にNavigateを書いてあるコントロールをSelectして実行させる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249807/21e6c629-f0af-8ae3-04c6-e12d15c4c8ea.png)
```
// スクリーンサイズで割り振り、管理者はAdmin画面へ
Set(StartMode,If(App.ActiveScreen.Size = Small,2,o365user.userPrincipalName in ManagersUPN.UPN,1,0));
Select(NaviFunk);
```
+ NaviFunkボタンの処理
OnVisibleで判定したStartModeに応じて各画面へNavigateする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249807/7929d95d-33e1-da3f-2297-34200198a875.png)
```
// 画面サイズ幅が600以下なら2の判定となり、スマホ用画面へ、管理者だったら管理画面へ、それ以外はメインのWeb版ユーザー登録画面へ
If(StartMode=0,Navigate(MainScreen),StartMode=1,Navigate(AdminScreen),StartMode=2,Navigate(MobileScreen))
```
+ 遷移するか確認
この段階で動作確認をやります。普通のアプリならブラウザで調整して確認可能ですが、Teams版なので発行して実機で試す必要がありました。。めんどいがしょうがなし。
・最初に追加した画面が開きローディング、しばらくしたらデバイスに応じた画面に遷移する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249807/9dcc5a23-261e-af27-cf1e-1b042e2346a6.png)

無事、スマホ版画面へ遷移しました。非対応とありますね（笑）
ブラウザ版でも試して想定通りか確認しましょう。

# ③ モバイル用画面のレイアウト調整ポイント
モバイル用画面の調整ですが、基本は以下の流れです。
+ 編集しやすいように画面の幅をいったん320くらいにしておく
+ Web版から各種コントロールを一気にコピペする
+ コンテナや各種コントロールの位置や幅などを調整する（レスポンシブに）
+ 必要に応じてスマホ用にコントロールの見た目や位置を変更する
+ 必要に応じてスマホ用に不要な処理を削除したり追加したり調整する


+ 編集しやすいように画面の幅をいったん320くらいにしておく
はそのままやるとPC画面幅の表示になってるのでイメージつかみずらいため。完了後に戻す感じ。※320のままだともっと表示できるスマホで右に隙間ができるのでダサいので後でMax(App.Width, App.MinScreenWidth)にします。

+ Web版から各種コントロールを一気にコピペする
色々割愛しますが、基本はWeb版につくったものをコピーして張りつけます。
その後にコンテナーや各コントロールなどの位置（主にX）と幅を調整していきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249807/dc745725-99b4-4a27-a86a-f91fc087eb17.png)

+ コンテナや各種コントロールの位置や幅などを調整する（レスポンシブに）
例：PC版ではギャラリーが左にあり右エリアに詳細画面となっていた。
スマホ版ではギャラリー部分のコンテナーの幅を以下のように調整して詳細開いた場合は幅0にし、詳細画面のコンテナは親からギャラリー部分コンテナーの幅を引いたサイズにする
使っている変数DetailShowは新規ボタンやレコード選択時にTrueにし、戻るや保存時にFlaseにする
→こうするとギャラリーと詳細画面の表示切替ができます。
・ギャラリー配置コンテナーの幅
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249807/e3df4c15-f2e4-9023-bf24-e5186719700b.png)
・詳細画面エリア配置コンテナーの幅
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249807/88573c7a-389b-9508-5876-2c310f37bd8e.png)
・新規ボタンやレコード選択で詳細画面のみ表示となる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249807/62e134e4-59be-f029-6859-a208798c3821.png)

+ X、Widthの調整ポイント
各コントロールのX座標と幅はParent.WidthやSelfなどを使って相対的な値にします（固定値にしない）
真ん中や右からどれくらいか、他コントロールと相対的な位置にするなど
```
Xの定義例：
真ん中　Parent.Width/2 - Self.Width/2
右端から30px前　Parent.Width- Self.Width - 30
右にあるコントロールから20px前　右コントロール.X - Self.Width- 20  
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249807/95f1f88e-d18c-7509-f599-48c25aa5d886.png)

+ フォームのカラム落ち
フォームは実はレスポンシブ対応そのまましてくれます。フォームに指定のカード幅が画面サイズに足りなければカラム落ちして表示されます。想定する幅に合わせて事前にカードサイズを調整しておけば大体いけます。
・幅400の場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249807/7c073a42-5dd1-6458-62cd-7c5d85d88e6f.png)
・320の場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249807/32314186-39c0-4f73-4642-b1d73da47e0f.png)

+ 必要に応じてスマホ用にコントロールの見た目や位置を変更する
スマホで操作しやすい位置や大きさに調整します。
・Web版では上部に表示していた経費合計部分は下に持ってきて、定期代、交通費は丸ボタンで”定”、”交”で表す
・操作エリアは上部でなく基本下に配置する。
※最近はおっきなスマホが多いですし下にあるほうが操作しやすいですよね。
※本来は削除ボタンは押し間違えのないように上部に移動させたほうがよいですね。
・Web版とスマホ版の比較
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249807/1bd228fa-8e83-0a24-7198-671cf81fa195.png)

+ その他調整
本当はデータテーブル部分もギャラリーに変更しようと思っていましたが、今回のケースでは意外にそのままでも悪くなかったのでそのまま使うことにしました。
データテーブルの特徴
・収まらない場合は横スクロールできるのでスライドで見れる
・列の幅も列の際をうまくつかめば広げて表示することができる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249807/3d80e107-bd54-1268-9993-83c6badc5793.png)

明細の修正画面はダイアログ表示でフォーム利用していた
→基本そのままで幅、位置の調整くらいで済んだ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249807/4268b639-e2fa-d1d2-617b-235ff7c8653f.png)

★添付ファイルコントロールでの表示がTeams版だと画面表示となるが戻るができない事象を確認。
スマホアプリ版だとDLするかなどの表示となるのですが、Teams版の仕様（不具合？）なのか、画面一杯に表示されて、前の画面には戻るアイコンなどなし、戻ろうとするとアプリを再度開く挙動となる。。
しょうがないので、編集時は注意する運用でカバー、閲覧時は添付ファイルコントロールを非表示にして名前とプレビュー表示、ボタンで大きく表示する機能を追加しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249807/cd6c5a4f-618f-4d8b-542f-ccd2ad578e0c.png)



という感じで調整して、適宜実機で状態を見つつ完了です。
実機やプレビューで見ると幅が広がっていない、位置がおかしいという点に気づきやすいです（レスポンシブにした後に触ったら固定値になってたりするので）
今回は思ったほど調整箇所がなかったので数時間で完了しました。2年間も待たせていたのに。。

# おわりに
今回はレスポンシブレイアウトでスマホ版画面を追加するサンプルでした。
別アプリを作成するほうが時間的には楽かと思いますが、レスポンシブ未体験の方はチャレンジしてみるのもいいかと思います。

**★他のアドベントカレンダー投稿記事はこちらです**
12/5[【ワンランク上のPower Apps】 CSVインポート その① パターン紹介編](https://qiita.com/youseibubu/items/dac102f67993413c3428)
12/6[【ワンランク上のPower Apps】 CSVインポート その② Automateで解析・登録編](https://qiita.com/youseibubu/items/1068b4e1e3ec0f36a5d8)
12/11[【ワンランク上のPower Apps】 CSVインポート その③ Automateで解析・Appsで登録編 ＆プログレス表示](https://qiita.com/youseibubu/items/b04358342098648326eb)