0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

SwiftUIの画面処理の仕方

Last updated at Posted at 2024-02-13

はじめに

SwiftUIを使用し、アプリを作成するとき、画面の処理の仕方がどうなるかを調査しました。

作成例

チェックをONにしたら、その項目の取り消し線を引くという例です。

スクリーンショット 2024-02-11 16.18.32.png

SwiftUIにはHTMLのチェックボタンずばりはありませんでした。
ToggleというUIコンポーネントが今回使用できそうなので代わりに使用しました。

上記画面のソース

ソース例を記載します。

import SwiftUI

// Task構造体: タスクのデータモデルを定義。IdentifiableとEquatableプロトコルに準拠しています。
struct Task: Identifiable, Equatable {
    let id: Int // タスクの一意識別子
    var title: String // タスクのタイトル
    var checked: Bool // タスクが完了したかどうかの状態
}

// ContentView: アプリのメインビューを定義する構造体。
struct ContentView: View {
    @State private var tasks = [ // タスクの配列を管理する状態変数。@Stateにより、UIが自動的に更新されます。
        Task(id: 1, title: "散歩", checked: true),
        Task(id: 2, title: "料理", checked: false),
        Task(id: 3, title: "筋トレ", checked: true)
    ]
    
    var body: some View {
        List { // リストビューを使用して、タスクの一覧を表示。
            ForEach($tasks) { $task in // $tasksを使用して、タスク配列の各要素に対するバインディングを生成し、ListRowに渡す。
                ListRow(taskTitle: $task.title, isChecked: $task.checked) // ListRowビューを使用して、各タスクを表示。
            }
        }
    }
}

// ListRow: リストの各行を定義するビュー。タスクのタイトルとチェック状態を表示する。
struct ListRow: View {
    @Binding var taskTitle: String // タスクタイトルのバインディング。外部からの変更を受け入れる。
    @Binding var isChecked: Bool // チェック状態のバインディング。外部からの変更を受け入れる。
    
    var body: some View {
        Toggle(isOn: $isChecked) { // トグルスイッチ。isCheckedの状態に基づいてON/OFFを切り替える。
            if isChecked {
                Text(taskTitle) // タスクがチェックされている場合、タイトルに取り消し線を表示。
                    .strikethrough()
                    .fontWeight(.ultraLight)
            } else {
                Text(taskTitle) // タスクがチェックされていない場合、通常のタイトルを表示。
            }
        }
    }
}

#Preview {
    ContentView()
}

上記の動き

SwiftUIのアプローチは以下のようになりました。

  • ON/OFFの切り替えと取り消し線の表示: @Bindingを使用してListRowビュー内のisChecked状態を監視し、この状態に基づいてToggleスイッチのON/OFFを反映し、条件に応じてTextに取り消し線を表示します。これはデータバインディングと宣言的UI記述の例です。

  • データの表示: @Stateプロパティラッパーを使用してContentView内のtasks配列の状態を管理し、ForEachを使って配列の各要素に対してループ処理を行い、データをビューにバインドします。これは状態管理と宣言的UI記述の例です。

  • 画面構成: ContentViewListRowビューを定義して、アプリのUIを構成します。ContentViewがアプリのメインビューを表し、ListRowがリストの各行を表すコンポーネントとして機能します。これはコンポーネント化の例です。

SwiftUIのアプローチ

SwiftUIで対応した特徴として、宣言的UI記述、状態管理、コンポーネント化、そしてデータバインディングがありました。WebのフロントのフレームワークのReactやVueに似ています。これらの概念を組み合わせることで、データの変更がUIに即座に反映され、ユーザーインタラクションを効率的に扱うことができます。
今回のアプリに当てはめると以下になります。

  • 宣言的UI記述: ContentViewListRowのビュー定義により、UIの構造と表示ロジックが明確に宣言されています。

  • 状態管理: @Stateプロパティラッパーにより、UIの状態が内部的に追跡され、状態の変更に応じてUIが自動的に更新されます。

  • コンポーネント化: ListRowビューにより、再利用可能なUIコンポーネントが作成され、UIの再利用性と保守性が向上します。

  • データバインディング: @Bindingプロパティラッパーにより、親ビューから子ビューへのデータの双方向バインディングが実現され、UIコンポーネント間でデータが効率的に同期されます。

SwiftUIの設計思想は、宣言的UIプログラミングパラダイムに根ざしています。このアプローチは、UIの状態と表示を密接に連携させ、状態の変更が直接UIの更新に反映されるようにすることを目指しています。

  • 状態の一元管理: @State, @Binding, @ObservedObjectなどのプロパティラッパーを使用することで、アプリケーションの状態を一元管理しやすくなります。これにより、状態の変更がUIのどの部分に影響を与えるかをシステムが把握し、必要な部分のみを効率的に更新できます。

  • データフローの明確化: データのバインディングと状態管理の仕組みにより、データがアプリケーションを通じてどのように流れるかが明確になります。これにより、バグの発生を減らし、コードの可読性と保守性を向上させることができます。

  • UIとロジックの密接な結合: UIの構造と表示ロジックを宣言的に記述することで、UIの見た目と動作を一箇所で管理できます。これにより、開発プロセスが簡潔になり、迅速なイテレーションが可能になります。

おわりに

Swiftの構造体、オプショナル型というSwiftに特徴的な型を踏まえた記載等も追加したかったですが、内容が広範囲になりまとまりもなくなるため割愛しました。SwiftとSwiftUIに詳しくない方々にも、これらの技術がどのように動作し、どのようなメリットを提供するのかざっくりわかれば幸いです。

参考記事

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?