本セッションの登壇者
セッション動画
「SwiftUIを上手に使う」というタイトルでiOSについてお話をしたいと思います。ふだんはヤフー株式会社でiOSアプリを開発しているたなたつです。よろしくお願いします。
最近、趣味でVTuberのようにアバターになってWeb会議に参加できるmacOS向けのアプリを開発しています。Zoomやこういうイベントで簡単にアバターになれるので、よかったら使ってみてください。
SwiftUIの良い使い方 - セマンティックでいこう
ではさっそく本題ですが、SwiftUIを上手に使うためには重要なポイントがあると自分は思っています。それは、セマンティックにUIをデザインするということです。
セマンティックでないデザインというのは、フォントサイズを具体的に何ポイントと指定したり、余白サイズをあえて指定したり、画面の右上にDoneボタンを置く/左上にCancelボタンを置くというように具体的にボタン位置を指定したりすることです。このようにするとSwiftUIの良さを最大限に活かしきれないケースがあります。
たとえばフォントサイズを具体的に指定していると、端末のDynamic Typeという機能で文字サイズを大きくしてもうまく反映されません。また、セマンティックでないレイアウト指定をすると、他のプラットフォームでは使えない機能が出てきます。たとえばwatchOSではこのnavigationBarTrailingという機能は使えないので、ビルドエラーになってしまいます。
一方、セマンティックなデザインというのは、ポイント数で指定していた部分をtitleというスタイルで指定するといったことです。テキストの役割や意味に合わせてスタイルを設定します。
たとえばパディングに関しても、あえて指定せずにプラットフォームに合った余白を設定したり、ボタンに関しても先ほどは右左を指定していましたが、confirmationAction と cancellationActionという、ボタン自体の意味で配置したりします。
このようにすることで、たとえばiOSの実装をwatchOSアプリとしてそのままビルドできます。フォントサイズも端末のサイズを大きくすれば「Hello, world」の部分が適切に大きくなります。また、iOSは右上にDoneボタン、左上にCancelボタンというのが一般的な実装ですが、意味で指定することによって自動的に配置されるので、配置ミスのない適切な配置になります。
さらに、このDoneボタンをよく見ると太字になっているように、正しいUXが自動的に適用されます。
このようにセマンティックにUIをデザインすることで、SwiftUIはかなりパワフルなものになります。Figmaなどのデザインツールでデザインしたものを完璧に実装で再現するといったフローで開発することが多いのではないかと思いますが、SwiftUIではそれはあまりお勧めできません。その理由は、先ほどお話ししたように、SwiftUIにはプラットフォームや環境に合わせた最適なUIを提供する機能があるからです。
さらに例を紹介すると、これらはほとんど共通のコードですが、このようにまったく見た目が違います。
左上はiOSで、リストというコンポーネントを使ってToDoリストを作った、よくあるiOSの見た目になっています。その隣がiPadOSです。iPadOSではリストはフルスクリーンではなくサイドバーとして表示して、右側は詳細画面のようなものを出す領域になっています。その下はwatchOSで、小さい画面でwatchOSらしい見た目になっています。そして右上はtvOS、その下がmacOSです。
このようにまったく見た目が違っていて、さらにダークモードやライトモードといった環境の設定でもまったく変わります。なので、たとえばデザインツールで、ある特定条件のデザインにおいて1ptの余白を調整したりしてしまうと、逆に別の条件ではその影響でUIが崩れてしまうこともあるかもしれません。難しいのですが、無駄なレイアウト指定をやめて、セマンティックにプラットフォームに任せたレイアウトをすることがけっこう重要になってきます。
デザインレビューの難しさ - やってみないとわからない側面も
(SwiftUIは)このような特徴のあるAPIなので、ブランドイメージや実現したいUXは残しつつ、できる限りSwiftUIに適応させることが大切になります。しかし、もちろんSwiftUIの知識なしにデザインを作ることはできません。したがって、デザインレビューというものが非常に大切になります。そしてその際にはSwiftUIの深い知識が必要です。
SwiftUIを意識したデザインレビューというのはなかなかに難しいなと、自分も日々思っています。SwiftUIのみで実現できるのか、UIKitなどと連携しなければならないのか、UIKitと連携する場合にはそれに対してどれくらい工数がかかるのか、どれくらい運用コストが増加するのか…といったことを考える必要があります。
本当にわずかな見た目の差でも、大幅に工数が変わります。ちょっとしたボーダーを消そうと思っても、その部分がSwiftUIではできなくて、UIKitで書かないといけないといったことがあったりします。かなり知識が必要になるのですが、SwiftUIは破壊的変更を繰り返しながら新しいAPIが増えたり消えたりしている状況なので、なかなか判断が難しくて、やってみないとわからないということも多いなと思っています。
おすすめはデザインを確定する前にXcode Previewsなどを使って、実装の難易度を確認することです。幸いなことにSwiftUIでは、Xcode Previewsを簡単に使えていろいろなバリエーションや環境でテストできるので、数分でサクっと確認するのがおすすめです。
独自のUIを採用したい場合の注意事項
ここまでの説明したように、すべてをセマンティックなデザインにすれば、SwiftUIの力を最大限に活用できますが、ビジネス上、どうしても独自のUIが必要な場合があります。UIKitなどと組み合わせれば独自のUIを作ることができますが、それによって自動的にさまざまな環境に適応してくれるSwiftUI本来の機能が使えなくなります。
たとえばダークモードにしたときに一部分だけ白いところが残ってしまったり、iPadOSでアプリを動かしたときにまるでiPhoneアプリを引き伸ばしたような見た目になってしまったり、iPadで横画面にできなかったりします。また、これは忘れがちなのですが、アクセシビリティに関しても、SwiftUIのコンポーネントを使っていればそれなりに正しく動くところが、カスタマイズしたことによってVoiceOverでの読み上げなどが適切に動かないことがあったりします。
簡単にレイアウトを作るだけならUIKitを使えばできますが、それによって本来対応できたはずのOSの便利な機能に対応できなくなってしまう、もしくは、対応するためにすごくコストがかかってしまう場合があるので、そういったトレードオフが発生するという理解が必要です。これはSwiftUIを知っている人でなければわからない部分なので、デザイナーやその他の関係者にこういった事情を共有する必要があります。
まとめ - 課題はあれどガンガンいこうぜ!
まとめですが、大切なのはセマンティックなUIデザインです。独自のUIを採用した場合には、さまざまなOSの便利機能のサポートを自分で実装したり、便利機能を無効にしたりする必要が出るので、思った以上のコストがかかるということをチームメンバー全員に共有する必要があります。
課題はありますが iOS 14以降ならSwiftUIを十分に使える状況なので、チーム全体で上手に使える力を身につけて、開発速度を一気に向上させると良いと思います。ガンガン使って知見をためていきましょう。
発表は以上になります。ありがとうございました。