swiftui

iOSアプリ開発

StateとObservableを使ってSwiftUIのビューを変更する方法

SwiftUIフレームワークを使っているとStateやObservedObjectと言った機能がよく使われています。特に、勉強を始めた頃などは「この機能が何をしているのか」や「どうやって使えばいいの?」と言った疑問があると思います。今回は、これらの機能についてわかりやすく解説していきます。

SwiftUIとは

今までiOSアプリ開発で使ってきたUIKitよりも、より簡単でインタラクティブにUIを実装できるようにしたフレームワークです。SwiftUIは設計自体が変わっていて、階層化されていてUIの配置がわかりやすくなっていたり、レイアウトなどを調整してくれるようになっていたり、デザインの変更が簡単にできるようにインターフェースがわかりやすくなっています。詳しくは、以下の記事を読んでみてください。

Stateとは

Property Wrappersで実装されていて、SwiftUIが提供しているAttributeの1つです。ビューに@Stateをつけた変数に変更があると、その時点でビューを更新するようになっています。Webのフロントエンドを開発している人は、ReactやVueで使われているStateプロパティに近いものと考えるとわかりやすいと思います。

@State var isSelected: Bool = false

Property Wrappersとは

State属性はProperty Wrappersという機能で実装されたものと説明しました。では、このProperty Wrappersとはなんでしょうか。この機能はAttributeを宣言する機能で、@を使ってプロパティの更新や取得時に何らかの処理を加えることができます。Stateは、値の更新時にUIの更新をする機能を持っていると言えます。

  • Attributeを宣言する機能で@を使ってアクセスできるようになる
  • Attributeはプロパティにつけるとことで特定の機能を持たせることができる
  • @ を使用することでプロパティへの独自のアクセスを提供する
  • @State @ObservedObject @Published などがあげられる

State属性を実際に使ってみる

State属性は以下のような機能を持っています。

  • @Stateをつけたプロパティに変更があるとその時点でUIを更新する
  • ReactやVueのStateプロパティに近い
  • $をつけることで本来の値にアクセスができる
  • 値はSwiftUIが持つStoreに保持される

この機能を利用して、ビューの色をかえるサンプルを実装してみます。


import SwiftUI

struct StateSampleView: View {
    @State var isSelected: Bool = false

    var body: some View {
        VStack {
            Button(action: {
                self.isSelected = !self.isSelected
            }) {
                Text("Change Color")
            }

            Circle().foregroundColor(isSelected ? .blue : .yellow)
        }
    }
}

ObservedObjectとは

State属性と似たようなAttributeに、ObservedObject属性というものがあります。ObservedObjectは、ObservableObjectプロトコルを適用したクラスを監視することができるようにします。ObservableObjectは、Combineフレームワークの機能の1つです。Combineは、非同期にイベントを処理するためのフレームワークです。ObservableObjectは、ReactiveプログラミングのSubscriberと同じような役割を持ています。以下のようなことができます。

  • 実装したクラスやモデルが持つプロパティを監視する
  • 監視しているプロパティが更新されると変更が通知される
  • ObservableObjectを適用したクラスの一部実装にPublished属性を利用することができる

ユースケースと実装例

今回は、ボタンを押すとサークルの色が変わるサンプルを実装してみます。内容は、Modelの値の変更を監視して変化したらサークルの色を更新というシンプルなものです。

モデルの実装は以下のようになります。変更があった場合に、objectWillChangeという値に通知を送ることでビューに伝達することができます。


import Foundation
import Combine

class ObservableModel: ObservableObject {
    var objectWillChange = PassthroughSubject<observablemodel, never="">()

    var isSelected: Bool = false {
        didSet {
            self.objectWillChange.send(self)
        }
    }
}

ビューの実装は以下のようになります。変更があると、ObservedObject属性を付与しているmodelに通知が行き、ビューを更新します。


import Foundation
import SwiftUI
import Combine

struct ObservableSampleView: View {
    @ObservedObject(initialValue: ObservableModel()) var model: ObservableModel

    var body: some View {
        VStack {
            Button(action: {
                self.model.isSelected = !self.model.isSelected
            }) {
                Text("Change Color")
            }
            Circle().foregroundColor(model.isSelected ? .blue : .yellow)
        }
    }
}

ObservedObjectは初期化する方法が2つある

最後に、ObservedObjectを付与したプロパティの初期化方法を紹介します。

ビューのinitの引数として渡す

1つ目は、ビューの初期化時に引数として渡してあげる方法です。


struct ObservableSampleView: View {
    @ObservedObject var model: ObservableModel
}

let view = ObservableSampleView(model: ObservableModel())

ObservableのinitialValueを使う

1つ目は、ビューの初期化時に引数として渡してあげる方法です。


struct ObservableSampleView: View {
    @ObservedObject(initialValue: ObservableModel()) var model: ObservableModel
}

swiftui初心者でもiOSアプリ開発ができるSwiftUIを触ってみようPrev

Firebase Firestoreを使ってiOSアプリのデータを管理する方法Next

Related post

  1. テクノロジー

    iOSアプリ開発者になる人が読んでいる12の本を紹介 2020年版

    「iOSエンジニアになるために、どんな本を読んで勉強すれば良いですか?…

  2. テクノロジー

    ReactiveXで使うStreamとObserverとは?RxJSでわかりやすく解説

    前回は、ReactiveXとは?RxJSの入門と導入手順について話しま…

  3. iOSアプリ開発

    iOSアプリ開発者が本当にオススメする6つの技術系サイト

    今回は、iOSアプリエンジニアとして実際に良く参考にしているサイトを紹…

  4. テクノロジー

    ReactiveXとは?RxJSの入門と導入手順

    Rx (Reactive Extension)とはここ数年で話題になっ…

  5. テクノロジー

    簡単にウェブページを公開できるFirebase Hostingの使い方を紹介

    ウェブページやサービスを作って公開したいけど、サーバーを立ち上げ方がわ…

  6. テクノロジー

    Appleの新しいMessagesで何ができるのか。

    WWDC 2016では数多くのセッションが行われました。WWDC 20…

PAGE TOP