こんにちは。中山です。
先日開催された WWDC 2019 で発表されました「 SwiftUI 」。
その、コードで UI を構築していくスタイルが、「どこかで見たことある」と思ったら、そう、「 Flutter 」でした。
今回は、SwiftUI と Flutter のコードを比較して、その特徴を探ってみたいと思います。
Hello World 的な画面
SwiftUI の場合
Apple の Developer サイトに早速用意されていた、SwiftUI の チュートリアルページ を見てみますと、以下のような、Swift UI での、いわゆる「 Hello World 」的な画面は、
SwiftUI では、以下のように実装します。
import SwiftUI struct ContentView: View { var body: some View { VStack(alignment: .leading) { Text("Turtle Rock") .font(.title) Text("Joshua Tree National Park") .font(.subheadline) } } } struct ContentView_Preview: PreviewProvider { static var previews: some View { ContentView() } }
Flutter の場合
これと同じような画面を Flutter で実装しますと、コードは以下のようになります。
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter App Sample', home: Scaffold( body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ Text( 'Turtle Rock', style: Theme.of(context).textTheme.title ), Text( 'Joshua Tree National Park', style: Theme.of(context).textTheme.subhead, ), ], ), ), ) ); } }
この Flutter のコードで生成される画面は、以下のような感じ。
Flutter のほうが、コード記述量が多いかなー、というところですが、基本的な構成はそれほど違わない印象を受けました。
リストビュー画面
SwiftUI の場合
シンプルな静的データを持つリストビューは、SwiftUI の場合、以下のような画面で、
これは、SwiftUI では、たとえば以下のように実装します。
import SwiftUI struct MyListItem: Identifiable { let id = UUID() let title: String let subtitle: String } let myListItems = [ MyListItem(title: "item1", subtitle: "description1"), MyListItem(title: "item2", subtitle: "description2"), MyListItem(title: "item3", subtitle: "description3"), MyListItem(title: "item4", subtitle: "description4"), MyListItem(title: "item5", subtitle: "description5") ] struct MyListItemRow: View { var myListItem: MyListItem var body: some View { HStack() { Spacer() VStack(alignment: .leading) { Spacer() Text(myListItem.title) .font(.title) Text(myListItem.subtitle) .font(.subheadline) Spacer() } Spacer() }.border(Color.gray, width: 2.0, cornerRadius: 8.0) } } struct MyListView: View { var body: some View { List(myListItems) { myListItem in MyListItemRow(myListItem: myListItem) } } } struct MyListView_Preview: PreviewProvider { static var previews: some View { MyListView() } }
Flutter の場合
Flutter の場合は、これと同じような画面を実装しますと、コードは以下のようになります。
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { final title = 'Flutter App Sample'; final listItems = [ { 'title': 'item1', 'subtitle': 'description1' }, { 'title': 'item2', 'subtitle': 'description2' }, { 'title': 'item3', 'subtitle': 'description3' }, { 'title': 'item4', 'subtitle': 'description4' }, { 'title': 'item5', 'subtitle': 'description5' } ]; return MaterialApp( title: title, home: Scaffold( appBar: AppBar( title: Text(''), backgroundColor: Colors.grey[200], ), body: ListView.builder( padding: const EdgeInsets.all(8.0), itemCount: listItems.length, itemBuilder: (BuildContext context, int index) { return Card( child: ListTile( title: Text(listItems[index]['title']), subtitle: Text(listItems[index]['subtitle']) ), ); }, ), ) ); } }
この Flutter のコードで生成される画面は、以下のような感じ。
どちらもシンプルではありますが、個人的には、SwiftUI のほうが、とっつきやすいような印象があるかなぁ。
画面遷移
SwiftUI の場合
SwiftUI の、シンプルな画面遷移の仕組みは、
SwiftUI コードでは以下のように実装します。
import SwiftUI struct FirstView: View { var body: some View { NavigationView { NavigationButton(destination: SecondView()) { Text("Show Second") .font(.title) } } } } struct SecondView: View { var body: some View { Text("Second") .font(.title) } } struct FirstView_Preview: PreviewProvider { static var previews: some View { FirstView() } }
Flutter の場合
Flutter の場合は、以下のようなコードになります。
import 'package:flutter/material.dart'; void main() { runApp(MaterialApp( title: 'Navigation Basics', home: FirstRoute(), )); } class FirstRoute extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('First'), ), body: Center( child: RaisedButton( child: Text('Show Second', style: Theme.of(context).textTheme.title), onPressed: () { Navigator.push( context, MaterialPageRoute(builder: (context) => SecondRoute()), ); }, ), ), ); } } class SecondRoute extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("Second"), ), body: Center( child: Text('Second', style: Theme.of(context).textTheme.title), ), ); } }
このときの Flutter のアプリの画面はこちら。
同じことをやってるんですが、SwiftUI のほうが、コードも洗練されてる印象かな。
まとめ
Flutter の登場により、UI をコードで書いていくスタイルが表舞台に現れたわけなのですが、正直なところ、Flutter がどの程度、開発現場に受け入れられているのか、というのが未知数であり、なかなか一歩を踏み出せずにいました。
しかし今回 SwiftUI がこのスタイルを踏襲した(ように見える)ことで、「今後はこの方向に進んでよいのだ」と、ある意味、背中を押してくれたような感じがしました。
今回は、シンプルな実装しか試していませんが、それでも、直感的に UI を実装できるこのスタイルは、非常に強力なツールになりうると感じました。