前回の記事 で 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 始めましょう。
投稿者プロフィール

最新の投稿
テクノロジー・専門技術2022年6月27日【iOS】ARケチャマヨバトルをアップデートしたときにやったこと
技術・開発情報2021年6月22日UIKit(Storyboard)で時間が止まってる人向けのiOS開発リハビリメニュー
技術・開発情報2020年10月8日AWSのSESを利用して手動でメールを送信する
技術・開発情報2020年9月8日SwiftUIのすすめ – 2. リスト表示 –