SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

ミニアプリを作って楽しく学ぶSwift

【作って学ぶSwiftアプリ開発入門】カウンター機能付きミニアプリを開発しよう!

ミニアプリを作って楽しく学ぶSwift入門 第3回

  • X ポスト
  • このエントリーをはてなブックマークに追加

Buttonでいいことをカウントする

いいことカウントを保存する変数を作成する

 カウントするためには、そのカウントを保存したり、値を確認できたりする必要があります。そこで使用するのが、前回学んだ変数です。

 いいことカウントを保存するための変数を作成して、いいことカウントボタンを押した時には、いいことカウントが1つ追加されるようにコードを次のように変更します。

struct GoodCounterView: View {
    
    // ↓ここを追加
    var goodCount = 0
    
    var body: some View {
        VStack {
            Text("いいことカウンター")
                .font(.largeTitle)
                .bold()
                .foregroundStyle(.pink)
            
            Text("100")
                .font(.system(size: 80))
            
            Button(action: {
                // 実行したい処理を記述
                // ↓ここを追加
                goodCount = goodCount + 1
            }, label: {
                Text("👍")
                    .font(.system(size: 100))
            })
        }
    }
}

 しかし、書き換えると、Cannot assign to property: 'self' is immutableというエラーが表示されます。これは「selfは値を変更できない(不変)状態なので、値を代入することができません」という意味で、このselfとはGoodCounterView: Viewのことになります。このGoodCounterViewstructで定義してあり、Swiftのstructはデフォルトで自身の値を変更できないようになっています。structの説明についてはここでは省略しますが、そのままの変数では値は変更できないという程度の理解で十分です。

 この値を変更するために、SwiftUIのViewでは値を更新する変数の頭に@Stateを付与する必要があります。

@Stateを学ぶ

 @Stateが付くと、その値がSwiftUIによって管理され、値を更新したり、現在の値を確認できたりします。

 @Stateの付いた値の変更は、SwiftUIが内部的に監視し、値が変更された際に自動的にUIを再描画してくれます。

 変数に@Stateを付ける場合は次のように記述します。

@State var goodCount = 0

 実際に変数goodCount@Stateを付けると、発生していたエラーが消えることを確認できます。

 @Stateの付いた変数には、private修飾子を付けることが推奨されているため、この修飾子も追加します。

@State private var goodCount = 0

 privateをつけると、その値に外部からアクセスができなくなり、意図しない値の変更を防ぐことができます。

いいことカウントを画面に反映する

 @Stateの付いた変数goodCountを用意し、いいことカウントボタンを押すとgoodCountが1つ追加されるようになりました。次にその値が画面に反映されるようにコードを変更します。

 これまで固定の100という文字を入力していた箇所に前回学んだ\()の記法を使用して変数の値を文字列として展開します。

 次のようにコードを変更してください。

struct GoodCounterView: View {
    
    @State private var goodCount = 0
    
    var body: some View {
        VStack {
            Text("いいことカウンター")
                .font(.largeTitle)
                .bold()
                .foregroundStyle(.pink)
            
            // ↓ここを変更
            Text("\(goodCount)")
                .font(.system(size: 80))
            
            Button(action: {
                goodCount = goodCount + 1
            }, label: {
                Text("👍")
                    .font(.system(size: 100))
            })
        }
    }
}

 プレビュー画面でいいことカウントボタンを押すと、いいことカウントが1つずつカウントアップできるようになりました。

 これでアプリ「毎日いいことカウンター」は完成です。

プロジェクトの整理をする

 アプリは完成しましたが、プロジェクトを少し整理していきます。

不要なファイルを削除する

 まずは不要なファイルは削除します。

 Xcodeのナビゲーターエリアの①ContentViewで右クリックを押して、表示された項目から②Deleteを選択します。

 次に「Do you want to move “ContentView.swift” to the Trash?」と削除するかを確認するダイアログが表示されるのでMove to Trashを押すと削除が実行されます。

 削除後に、Xcodeのナビゲーターエリアが次のようになれば完了です。

アプリ起動時に表示する画面を設定する

 ContentViewの削除により、MyAppCollectionAppを表示するとCannot find 'ContentView' in scopeというエラーが表示されています。これはContentViewが見当たらないことで発生しているエラーになります。

 削除したContentViewの代わりに今回作成したGoodCounterViewを設定します。

@main
struct MyAppCollectionApp: App {
    var body: some Scene {
        WindowGroup {
            // ↓ここを変更
            GoodCounterView()
        }
    }
}

 ここで記載されている@mainは、アプリのエントリーポイントを指定するために使用されます。 @mainを使用すると、そこが起動時に最初に実行されるポイントとして認識されます。

iOSシミュレーターで動作を確認する

 これまでアプリの動作はプレビュー画面で確認してきましたが、@mainのアプリのエントリーポイントとして指定したGoodCounterViewが正常に動作するか、Xcodeの実行ボタンを押して、iOS シミュレーターで実行してみましょう。

 iOS シミュレーターが立ち上がり、次のように表示されれば完了です。ぜひ、その日にあったいいことを数えてみてください。自分が思っている以上に沢山のいいことがあることに気づくことができます。

まとめと次回

 今回は毎日いいことカウンターアプリを作る過程で、SwiftUIでの縦並びやTextButtonについて学びました。また、今回は詳細の説明を省略した以下のトピックについて気になった方はぜひ調べてみてください。

  • アクセス修飾子
  • struct

 実は、今回の毎日いいことカウンターアプリのいいことカウントは永続化されていないため、アプリを起動する度にカウントは0に戻ってしまいます。永続化したい場合は、@AppStorageを変数goodCountにつけると永続化できるようになるのですが、今回の説明は省略します。チャレンジしたい方はぜひ調べてみてください。

 次回はアプリ「やるのかやらないのかコイントス」を作ります。お楽しみに!

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
ミニアプリを作って楽しく学ぶSwift連載記事一覧

もっと読む

この記事の著者

リルオッサ(リルオッサ)

 ブレイクダンサー、時々iOSエンジニア。元ブレイクダンス世界2位。 現在は、楽しいことを追い求め、iOSアプリを作ったり、ビールを飲んだり、絵を書いたり、技術記事を書いたり、海外登壇チャレンジしたり、ブレイクダンスの大会を企画したりしています。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

CodeZine編集部(コードジンヘンシュウブ)

CodeZineは、株式会社翔泳社が運営するソフトウェア開発者向けのWebメディアです。「デベロッパーの成長と課題解決に貢献するメディア」をコンセプトに、現場で役立つ最新情報を日々お届けします。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/20660 2025/01/24 11:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング