FlutterでiOSアプリを作る際、UIに違和感を覚えるときはないでしょうか?
これはFlutterがマテリアルデザインを採用しているためであり、iOSっぽいUIを作るには工夫が必要です。
一応公式でも「CupertinoWidget」というiOS向けのUIにする方法はあるのですが、個人的に使い勝手が悪いと感じたのであまり使いたくありません。
そこで今回はマテリアルデザインのままiOSぽさを出してみようと思います。
マテリアルデザインのAppBarとBottomNavigationBarはクパチーノデザインのものと違い縦幅が大きく、elevationと呼ばれるウィジェットが浮いているように見える影のようなものがついています。
個人的にこの違いがiOSぽさをなくしているように感じるので、この部分をいじってみます。

わかりにくいですが、これだけでもiOSぽさが出ています。
以下コード全文です。
import 'package:description/home_page.dart';
import 'package:description/profile.dart';
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);
  
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Root(),
    );
  }
}
class Root extends StatefulWidget {
  const Root({Key? key}) : super(key: key);
  
  State<Root> createState() => _RootState();
}
class _RootState extends State<Root> {
  int _currentIndex = 0;
  final _pageWidgets = [
    //bodyの部分をここで設定
    const HomePage(),
    const Profile(),
  ];
  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: PreferredSize(
        preferredSize: const Size.fromHeight(43.0),
        child: AppBar(
          title: const Text('タイトル'),
          elevation: 0,
        ),
      ),
      body: _pageWidgets.elementAt(
        _currentIndex,
      ),
      bottomNavigationBar: Container(
        height: 48,
        decoration: const BoxDecoration(
          border: Border(
            top: BorderSide(
              color: Colors.black,
              width: 0.1,
            ),
          ),
        ),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: [
            GestureDetector(
              onTap: () {
                _onItemTapped(0);
              },
              child: const Icon(
                Icons.home,
              ),
            ),
            GestureDetector(
              onTap: () {
                _onItemTapped(1);
              },
              child: const Icon(
                Icons.person,
              ),
            ),
          ],
        ),
      ),
    );
  }
  void _onItemTapped(int index) => setState(() => _currentIndex = index);
}
簡単にコードの解説をしていきます。
まずAppBarをPreferredSizeで囲うことで高さの設定ができるようになります。
appBar: PreferredSize(
  preferredSize: const Size.fromHeight(43.0),
  child: AppBar(
    title: const Text('タイトル'),
    elevation: 0,
  ),
),
AppBarは簡単ですが、BottomNavigationBarは少し難しいです。
SizedBoxなどで囲んで高さを調節してもいいですが、端末のサイズが異なったときにエラーが出ることがあります。
なので今回はBottomNavigationBarを使わずにUIを自作しました。
(今回はdecorationでborderを作り、bodyとの境目をわかりやすくしていますがなくても大丈夫です。好みで変更してください。)
bottomNavigationBar: Container(
  height: 48,
  decoration: const BoxDecoration(
    border: Border(
      top: BorderSide(
        color: Colors.black,
        width: 0.1,
      ),
    ),
  ),
  child: Row(
    mainAxisAlignment: MainAxisAlignment.spaceAround,
    children: [
      GestureDetector(
        onTap: () {
          _onItemTapped(0);
        },
        child: const Icon(
          Icons.home,
        ),
      ),
      GestureDetector(
        onTap: () {
          _onItemTapped(1);
        },
        child: const Icon(
          Icons.person,
        ),
      ),
    ],
  ),
),
AppBarとBottomNavigationBarが違うだけでもiOSぽさが出ていい感じになりました。
みなさんもiOSアプリを作るときにUIの参考にしてみてください。
可茂IT塾ではFlutter/Reactのインターンを募集しています!可茂IT塾のエンジニアの判断で、一定以上のスキルをを習得した方には有給でのインターンも受け入れています。
Read More可茂IT塾ではFlutter/Reactのインターンを募集しています!可茂IT塾のエンジニアの判断で、一定以上のスキルをを習得した方には有給でのインターンも受け入れています。
Read More