【Flutter/Dart】CupertinoPageScaffoldの使い方!iOSライクなUI実装

この記事からわかること
- Flutter/DartのCupertinoPageScaffoldとは?
- iOSライクなUIの実装方法
index
[open]
\ アプリをリリースしました /
環境
- Android Studio:Koala
- Xcode:16.0
- Flutter:3.29.2
- Dart:3.7.2
- Mac M1:Sonoma 14.6.1
公式リファレンス:CupertinoPageScaffold
CupertinoPageScaffold
FlutterのCupertinoPageScaffold
はアプリの基本的なレイアウト構造を、iOSライクなUIをベースとして構築するための土台となるWidgetです。Cupertinoと付与されているWidgetは基本的にiOSのUIに準じたデザインベースになっておりiOSライクなUIを簡単に実装できるようになっています。
CupertinoPageScaffold
ではナビゲーションバー(上部バー)の実装も簡単に可能になります。
定義を確認してみるとプロパティはそれほど多くはなく、navigationBar
やchild
が基本的な部分になります。
class CupertinoPageScaffold extends StatefulWidget {
const CupertinoPageScaffold({
super.key,
this.navigationBar,
this.backgroundColor,
this.resizeToAvoidBottomInset = true,
required this.child,
});
}
AndroidライクなUI(マテリアルデザイン)での実装をしたい場合はScaffold
Widgetを使用してください。
CupertinoPageScaffoldの使い方
CupertinoPageScaffold
は土台部分を構成するWidgetなので画面単位の土台として活用します。
class MyCupertinoPage extends StatelessWidget {
const MyCupertinoPage({super.key});
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: const Text('Cupertino Example'),
trailing: CupertinoButton(
padding: EdgeInsets.zero,
child: const Icon(CupertinoIcons.add),
onPressed: () {
// 右上のボタンが押されたときの処理
print('ボタンが押されました');
},
),
),
child: SafeArea(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
Text('CupertinoPageScaffold'),
],
),
),
),
);
}
}
CupertinoNavigationBar
コンストラクタの引数navigationBar
はナビゲーションバー(上部バー)部分のUIを構築するWidgetを指定します。定義を確認すると指定できる型はObstructingPreferredSizeWidget?
になっています。PreferredSizeWidget
は高さが明示的に指定されているという特徴があり、これをラップしたクラスが指定されています。
/// CupertinoPageScaffoldの上部に表示されるappBar
final ObstructingPreferredSizeWidget? navigationBar;
CupertinoNavigationBar
はObstructingPreferredSizeWidget
を継承しているので基本的にCupertinoNavigationBar
を使用すればOKです。カスタムで実装したい場合はObstructingPreferredSizeWidget
を継承させる必要があります。
navigationBar: CupertinoNavigationBar(
// 中央に表示されるUI
middle: const Text('Cupertino Example'),
// 右側に表示されるUI
trailing: CupertinoButton(
padding: EdgeInsets.zero,
child: const Icon(CupertinoIcons.add),
onPressed: () {
// 右上のボタンが押されたときの処理
print('ボタンが押されました');
},
),
)
child
コンストラクタの引数child
は画面に表示するメインコンテンツを指定します。Widget
型で指定できるので任意のUIを指定することが可能ですが、以下のように普通に実装するとnavigationBar
のUI領域に隠れてしまいます。
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: const Text('Cupertino Example'),
trailing: CupertinoButton(
padding: EdgeInsets.zero,
child: const Icon(CupertinoIcons.add),
onPressed: () {
print('ボタンが押されました');
},
),
),
// 以下のようにchild直下にそのまま指定するとnavigationBarのサイズを検知できていないので隠れてしまう
child: Column(children: const [Text('CupertinoPageScaffold')]),
);
これを解消するためにはSafeArea
を使用します。SafeArea
はデバイスの画面の端にあるセンサー領域やノッチ、ステータスバー、ナビゲーションバーなどのインタラクティブなUI要素を避けて、コンテンツを表示するためのWidgetです。これでラップすることでUIが隠れることなく表示されるようになります。
child: SafeArea(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
Text('CupertinoPageScaffold'),
],
),
),
),
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。