Power Apps モダンコントロールを使ってみた Part.4

Power Apps
この記事は約15分で読めます。

前回はPower Appsのモダンコントロール「テーブル」の設定項目と機能についての解説、そしてタブ一覧とテーブルを組み合わせた簡易アプリの完成までを解説しました。
今回は前回告知した通りスピナーについての解説を行おうと思います。
スピナーの利用場面としては「画面ロード中の処理状態を示す」「ボタン操作で処理を行った際の処理中を表す」等いろいろな場面が想定されます、また「スピナーを表示中はアプリ上の操作をさせたくない」というのも一つの利用ケースでしょう。そんな際に少しでもお役に立てる記事になれれば幸いです。

スピナー

サンプルプログラム

サンプルプログラムをGitHubにて配布しています。
ForkまたはDownloadしてご自身の開発環境にインポートしてください。
ファイル形式はzipでフォルダ階層はpowerapps/Spinner_Sample/SpinnerSample.zipとなっています。

設置方法

スピナーは、コントロールの分類として「ディスプレイ」に分類されています。
以下2通りの方法で設置することが可能です。

  • リボンメニュー(✚挿入) > ディスプレイ > Spinner
  • アイコンメニュー(✚) > ディスプレイ > Spinner
リボンメニュー
アイコンメニュー

表示

Z-Index(配列)

コントロールの設定値には存在しませんが、Z-Indexは重要度の高い設定値となります。

設定は画面上の配列で行います。
下の画像ではRectangle1が最も背面(Z-Index = 0)
TextCanvas1が最も前面(Z-Index = 4)に配置されています。

コントロール配置
配置されたコントロールの重なり

画像ではスピナーを中心に二つの四角形を配置しています。【TextCanvas】は四角形の配列を表すために配置しました。スピナーよりも前面に配置された【Rectangle2】はスピナーの右上4分の一を覆い隠しています。また、スピナーの背面に配置された【Rectangle1】の右上4分の一はスピナーに覆い隠されています。
いずれも覆い隠された箇所は操作が出来ない箇所となってます。
画像のコントロール設定は以下のとおりです。

/* TextCanvas1 */
Text = "Z-Index = 2"
Color = RGBA(255,255,255,1)
X = Rectangle2.X
Y = Rectangle2.Y + Rectangle2.Height / 2 - Self.Height / 2
Width = Rectangle2.Width
Height = 32
Size = 16

/* Rectangle2 */
Fill = App.Theme.Colors.Lighter50
X = Spinner1.X + Self.Width / 2
Y = Spinner1.Y - Self.Height / 2
Width = 200
Height = 200

/* Spinner1 */
Label = "Is Loading ..."
LabelPosition = 'Spinner.LabelPosition'.Before
X = Parent.Width / 2 - Self.Width / 2
Y = Parent.Height / 2 - Self.Height / 2
Width = 200
Height = 200
Appearance = 'Spinner.Appearance'.Inverted

/* TextCanvas2 */
Text = "Z-Index = 0"
Color = RGBA(255,255,255,1)
X = Rectangle1.X
Y = Rectangle1.Y + Rectangle1.Height / 2 - Self.Height / 2
Width = Rectangle1.Width
Height = 32
Size = 16

/* Rectangle1 */
Fill = App.Theme.Colors.Darker50
X = Spinner1.X - Self.Width / 2
Y = Spinner1.Y + Self.Height / 2
Width = 200
Height = 200

Visible(General)

他のコントロールでは表示されていることが当たり前・・・・なのであまり気にしない設定値・・・・・・・・・・・・・・ですが、スピナーではこの値が最も重要な制御項目となります。
常に表示されていては他のコントロールの表示の邪魔になります。ボタンに重なっていた場合はボタンが操作できない事態を引き起こします。また、必要な時に表示されないようでは設置した意味がありません。
ここは確実に必要な時だけ表示される設定を心掛けましょう!

表示の制御

制御方法としてはいくつか考えられますが、以下の3通りの制御方法がメインではないかと思います。

  • ループ処理などの終了を待つ
  • タイマーを使用する
  • 条件によりフラグを立てて表示・非表示を切り替える

処理に何秒かかるか見当もつかないけど処理中は操作を待ってほしい!という場合に。

スピナー表示 > 処理の実行 > 処理の終了 > スピナー非表示

基本の設定例で、非常にシンプルで確実に動作します。

/*
    変数の定義
    App.OnStartやScreen.OnVisibleで定義
*/
// スピナー表示用変数(規定はオフとする)
Set( SpinnerOnVisible, false );

/*
    コントロールの制御
    制御する画面内に属するコントロールの動作プロパティに記述する。
    OnStart, OnVisible, OnSelect...等
*/
// スピナーを表示する。
Set( SpinnerOnVisible, true );
<Todo>
Set( SpinnerOnVisible, false );

/*
    スピナーの設定
*/
// Spinner.Visible
SpinerOnVisible

<ToDo>部分の処理にかかる時間が十分に短い場合はスピナーが表示されていない様にも見えます、しかしスピナーの動作としては狙い通りです。

確実にn秒は待ってほしい!という場合にタイマーが役立ちます。

タイマースタート=スピナー表示 > タイマーエンド=スピナー非表示

拡張性に乏しい設定例ですが、非常にシンプルで確実に動作します。

/*
    変数の定義
    App.OnStartやScreen.OnVisibleで定義
*/
// スピナー表示(規定はオフとする)兼タイマー制御用変数
Set( SpinnerOnVisible, false );

/*
    コントロールの制御
    Screen.OnVisibleやBotton.OnSelectに記述する
*/
// タイマーをスタートすると共にスピナーを表示する。
Set( SpinnerOnVisible, true );

/*
    スピナーの設定
*/
// Spinner.Visible
SpinerOnVisible

/*
    タイマーの設定
*/
// Timer.Start
SpinnerOnVisible
// Timer.Duration
任意の値(msec)
// Timer.OnTimerEnd
<ToDo>
Set( SpinnerOnVisible, false )    /* 必ず最後の行に記述! タイマーをオフにすると共にスピナーを非表示にする */

<ToDo>部分にループなどの処理を追加した場合、最低”Duration”分の時間はスピナーが表示されます。”Duretion”以上に処理に時間がかかった場合は、処理が終了するまでスピナーが表示され続けます。

タイマースタート > スピナー表示 > スピナー非表示 > タイマーストップ

シンプルで確実に動作する上拡張性も豊富です。

/*
    変数の定義
    App.OnStartやScreen.OnVisibleで定義
*/
// スピナー表示用変数(規定はオフとする)
Set( SpinnerOnVisible, false );
// タイマー制御用変数(規定はオフとする)
Set( StartTimer, false );

/*
    スピナーの設定
*/
// Spinner.Visible
SpinerOnVisible

/*
    タイマーの設定
*/
// Timer.Start
StartTimer
// Timer.Duration
任意の値(msec)
// Timer.OnTimerStart
Set( SpinnerOnVisible, true ); /* タイマースタートの瞬間スピナーを表示 */
// Timer.OnTimerEnd
<ToDo>
Set( SpinnerOnVisible, false ); /* スピナーを非表示にする */
Set( StartTimer, false )    /* 必ず最後の行に記述! タイマーをオフにする */

<ToDo>部分にループなどの処理を追加した場合、最低”Duration”分の時間はスピナーが表示されます。”Duretion”以上に処理に時間がかかった場合は、処理が終了するまでスピナーが表示され続けます。

忘れがちなのが、Timer.OnTimerStartの記述です、記述を忘れた場合はタイマーはスタートしてストップしますが、スピナーは表示されません。

複数の処理を同時に実行して、条件に応じてスピナーの表示を行いたい場合。
ボタンやタイマーを複数設置し起動状態を監視することで条件判断しフラグを設定します。

ボタンn個による処理の並行実行

ボタンの場合押されているかどうかの判断が非常に難しいため、処理状態を表すフラグ変数を定義する必要があります。
また、条件を満たすか?という判断を行うため各処理終了後に判断を行う必要があります。

/*
    変数の定義
    ボタンの個数 n = 3 とする
    App.OnStartやScreen.OnVisibleで定義
*/
// スピナー表示(規定はオフとする)兼タイマー制御用変数
Set( SpinnerOnVisible, false );
// 1個目のボタンの処理状態(規定はオフとする)
Set( ButtonActive1, false );
// 2個目のボタンの処理状態(規定はオフとする)
Set( ButtonActive2, false );
// 3個目のボタンの処理状態(規定はオフとする)
Set( ButtonActive3, false );

/*
    コントロールの制御
    Screen.OnVisibleに記述する場合は最終行などに工夫する。
  または、TriggerBotton.OnSelect(処理実行用のボタンとは異なるトリガーとなるボタン)に記述する。
*/
Set( SpinnerOnVisible, true );
// 1個目のボタンの処理開始
Select( ButtonCanvas1 );
// 2個目のボタンの処理開始
Select( ButtonCamvas2 );
// 3個目のボタンの処理開始
Select( ButtonCanvas3 );

/*
    スピナーの設定
*/
// Spinner.Visible
SpinerOnVisible

/*
    ボタンの設定
    すべてのボタン共通([n]はボタンナンバーに変換)
    BottonCanvas[n].OnSelect
*/
Set( BottonActive[n], true );
<ToDo>
Set( BottonActive[n], false );
Set( SpinnerOnVisible, Or( Botton1Active, Botton2Active, Botton3Active ) )    /* 必ず最後の行に記述! すべてのボタンが処理を行っていない場合はスピナーを非表示とする。 */

Set( SpinnerOnVisible, Or( Botton1Active, Botton2Active, Botton3Active ) )
この部分のOrが重要です。
Set( SpinnerOnVisible, And( Botton1Active, Botton2Active, Botton3Active ) )
としてしまうと、いずれかが処理を開始すると非表示となり、すべてが終了した時点で表示されます

タイマーn個による処理の並行実行

シンプルで確実に動作する上拡張性も豊富です。

/*
    変数の定義
    タイマーの個数 n = 3 とする
    App.OnStartやScreen.OnVisibleで定義
*/
// スピナー表示用変数(規定はオフとする)
Set( SpinnerOnVisible, false );
// 1個目のタイマー起動状態(規定はオフとする)
Set( Timer1Active, false );
// 2個目のタイマー起動状態(規定はオフとする)
Set( Timer2Active, false );
// 3個目のタイマー起動状態(規定はオフとする)
Set( Timer3Active, false );

/*
    スピナーの設定
*/
// Spinner.Visible
SpinerOnVisible

/*
    タイマーの設定
    すべてのタイマー共通([n]はタイマーナンバーに変換)
    Timer[n].[Property]
*/
// Timer[n].Start
Timer[n]Active
// Timer[n].Duration
任意の値(msec)
// Timer.OnTimerEnd
<ToDo>
Set( Timer[n]Active, false );
Set( SpinnerOnVisible, Or( Timer1Active, Timer2Active, Timer3Active ) ); /* スピナーを非表示にする */

/*
    スピナーの表示とタイマーの起動
    App.OnStart, Screen.OnVisible, ButtonCanvas.OnSelect, Gallary.OnSelectなどに記述可能
*/
// スピナーを表示
Set( SpinnerOnVisible, true );
// 1個目のタイマーを起動
Set(Timer1Active, true );
// 2個目のタイマーを起動
Set(Timer2Active, true );
// 3個目のタイマーを起動
Set(Timer3Active, true );

ボタンの場合画面上からしかアクセスできませんが、タイマーはアプリ起動時にアクセス可能となります、アプリ起動時に複数の処理を行い囚虜を待ってから画面遷移したい場合などに有効な使い方です。

ラベル

テキスト

[ラベル]にはスピナー表示中に何をしているか・・・・・・・を示すような”テキスト”を設定できます。空白も可能です。
”テキスト”には計算式や関数も利用できます。

ラベルのテキスト設定例
// Spinner.Label プレーンテキストを表示する
"画面の読み込み中。"

/*
    他所で定義した変数を利用する場合
// Screen.OnVisible等で定義
Set( args, "画面");

// Spinner.Label 変数を利用する
$"{args}の読み込み中。"
// または
args & "の読み込み中。"

*/

/*
    現在のスクリーン名を使用する場合
$"{App.ActiveScreen.Name}の読み込み中"
// または
App.ActiveScreen.Name & "の読み込み中"
*/

表示位置

ラベルの表示位置は4か所選択出来ます。以下がその対応表です。

設定値表示位置基準テキストの折り返し基準幅
Aboveスピナー画像スピナー枠の幅
Afterスピナー画像スピナー枠の幅 – スピナー画像の幅
Belowスピナー画像スピナー枠の幅
Beforeスピナー画像スピナー枠の幅 – スピナー画像の幅
スピナーラベルの表示位置対応表(上から時計回り)
Above
After
Below
Before

外観

設定値としての【外観】

スピナーの設定項目では[Stayle and potision]カテゴリに含まれず、[Style and theme]に含まれている【外観】(Appearance)が存在します。この設定値はスピナー枠内の背景色とスピナー色、ラベルテキストを反転して表示する設定となっています。

設定値テーマ色で表示白で表示
Primaryスピナー色背景色
Invarted背景色スピナー色、ラベルテキスト
外観設定対応表
Sryle and theme 拡大表示
Primary 表示
Inverted 表示

スピナーレイアウトサイズ

スピナーコントロール自体のサイズです。
プロパティは幅が [Width]、高さが [Height]です。
「スピナー表示中はアプリ上の操作をさせたくない!」といった場合、幅と高さを画面いっぱいに設定し、最前面に配置すれば他のコントロールにアクセスできなくなりますので、操作を抑制することが可能です。

レスポンシブを意識したサイズ設定では、画面サイズが変化した際に追従する必要があります。
CSSでは Width: 100%; Height: 100vh で追従しますが、Power Appsでは設定できません。
代わりに変数を使って追従させます。

Width = Parent.Width
Height = Parent.Height

上のコードを[Width], [Height]に設定するだけで画面サイズが変化してもレイアウトサイズが追従します。

スピナーサイズ

スピナーサイズは7段階から選択できます、最小時と最大時で約3倍のサイズ差となります。個人の感想ですが、スマホをターゲットとしたサイズ設定なのでしょうか?もう少し大きくしたいと感じるサイズです。

スピナーサイズ Tiny
Tiny
ExtraSmall
Small
Medium
Large
ExtraLarge
Huge

まとめ

今回はスピナーについて設定例・制御例など解説を行いました。
スマホ専用アプリの場合はスピナーサイズを画面いっぱいにして操作できないようにするなどがいいかと思います。PCブラウザ対応アプリの場合ですと、水平コンテナや垂直コンテナを複数配置してレスポンシブ対応にした上で、コンテナーごとにスピナーを配置して処理中は操作を不可能にするなども可能です。
また次回紹介します「進行状況バー」との組み合わせで、より進行度合いのわかりやすいUIが作成できると思いますので、次回をお楽しみにしていただきたいと思います。

この記事を書いた人

岩本敏彦
タイトルとURLをコピーしました