前回の記事 で SwiftUI の魅力をお伝えしましたが、今回から実際の UI パーツの実装をしていきたいと思います。
まずはアプリの基本となるリスト表示です。
UIKit で実装したことのある方だと、「UITableView を使って Delegate と DataSource を設定して…」という手順が思い浮かぶかと思いますが、SwiftUI では Delegate などのコールバック的な処理は必要としません。
struct ContentView: View { var body: some View { List { Text("Google") Text("Apple") Text("Facebook") } } }
これだけです。
これを実行(もしくは Xcode のプレビュー)すると、リスト表示ができていることがわかります。
次に配列を表示してみます。
struct ListView: View { private var items = ["Google", "Apple", "Facebook", "Amazon", "Microsoft", "Twitter", "TOYOTA", "Baidu", "LINE", "Tesla"] var body: some View { List { ForEach(items, id: \.self) { item in Text(item) } } } }
ForEach の中に id: .self という見慣れない書き方がありますが、これは List 内で要素を識別するのに ID が必要なためです。
List 内のデータの要素(この場合は items)を構造体にして id というプロパティを用意すれば不要になるのですが、ここでは深く触れないこととします。
実行するとこうなります。
さらに、項目を追加できるようにしてみます。
struct ListView: View { @State private var showInputModal = false @State private var newName = "" @State private var items = ["Google", "Apple", "Facebook", "Amazon", "Microsoft", "Twitter", "TOYOTA", "Baidu", "LINE", "Tesla"] var body: some View { ZStack(alignment: .bottomTrailing) { List { ForEach(items, id: \.self) { item in Text(item) } } .sheet(isPresented: $showInputModal, onDismiss: { if (self.newName != "") { self.items.append(self.newName) self.newName = "" } }) { ListInputView(name: self.$newName) } Button(action: { self.showInputModal.toggle() }) { Image(systemName: "plus.circle.fill") .resizable() .frame(width: 50, height: 50) } .padding() } } }
struct ListInputView: View { @Environment(\.presentationMode) var presentationMode @Binding var name: String var body: some View { VStack{ Spacer() Text("企業名を入力") TextField("企業名", text: $name) .textFieldStyle(RoundedBorderTextFieldStyle()) Spacer() HStack { Spacer() Button(action: { self.name = "" self.presentationMode.wrappedValue.dismiss() }) { Text("キャンセル") } Spacer() Button(action: { self.presentationMode.wrappedValue.dismiss() }) { Text("OK") } .disabled(name.count == 0) Spacer() } } .padding() } }
色々と新しい要素が出てきました。
まず @State ですが、これが付けられた変数は「状態変数」となり、変数の値が変わるとビューが再描画するようになります。
sheet ではモーダルで表示するビューを定義します。
showInputModal の値によって表示状態が決まり、onDismiss でビューが消える際の処理を書きます。
ListInputView は実際に表示されるビューです。
このモーダルビューを表示するトリガが Button です。
action にタップ時の処理を書きます。
また、Button をList の前面に表示するために、全体を ZStack (Z 方向のレイアウト)で囲んでいます。
ListInputView では name を設定して、元のビューに返しています。
こちらのビューの細かい説明は省きますが、@Binding で宣言した変数はビューと同期されるようになり、ここで入力された値が自動的に name に入り、それが元のビューにまで反映されます。
実行するとこんな感じ。
(サンプル用に作ったアプリを流用しているので、ナビゲーションバーが付いていることは気にしないでください)
…と、こんな感じでよくあるリスト表示と項目の追加が実装できました。
UIKit だったらリスト表示だけでなく、モーダルの画面とのデータやりとりも考えないといけないので、それと比べるとかなり簡潔にコードが書けることがわかるかと思います。
iOS エンジニアの皆さん、少しずつ SwiftUI 始めましょう。
投稿者プロフィール
最新の投稿
- iOS2022年6月27日【iOS】ARケチャマヨバトルをアップデートしたときにやったこと
- iOS2021年6月22日UIKit(Storyboard)で時間が止まってる人向けのiOS開発リハビリメニュー
- 技術開発2020年10月8日AWSのSESを利用して手動でメールを送信する
- iOS2020年9月8日SwiftUIのすすめ – 2. リスト表示 –