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?

【SwiftUI】前回のToDoListで完了率が反映されなかった原因と修正版(TabViewでのViewModel共有)

Last updated at Posted at 2025-11-05

🧩 はじめに
以前投稿した「ToDoListアプリで完了率をグラフ表示する」記事 https://qiita.com/kenshin_jp_13/items/52219325c7924075b039 で、
タスクにチェックを入れてもグラフの完了率が変わらないという不具合がありました。
今回はその原因と、正しく反映されるように修正したコードを紹介します。

💥 問題の症状
タスク一覧とグラフを TabView で切り替えるようにしていたのですが、
チェックを入れてもグラフ側が更新されないという状態でした。

⚠️ 問題のコード(修正前)

struct ChartView: View {
    @ObservedObject var ListVM = ListViewModel()
    var body: some View {
        VStack {
            Chart {
                ForEach(ListVM.taskStats, id: \.category) { stat in
                    SectorMark(angle: .value("割合", stat.count))
                }
            }
            Text("完了率:\(ListVM.completionRate, specifier: "%.1f")%")
        }
    }
}

ListView 側でも同じように

@StateObject var ListVM = ListViewModel()

を使っていました。

🎯 原因
SwiftUIの @StateObject / @ObservedObject は、
各ビューが独自に持つインスタンスになります。
つまり:
📋 ListView → 自分専用の ListViewModel()
📊 ChartView → 別の ListViewModel()
結果、タブごとに別々のデータを見ていたため、
リストで変更してもグラフには反映されなかった、というわけです。

✅ 解決方法:ViewModelを共有する
アプリ全体で同じデータを使いたいときは、
上位ビューで @StateObject を1つだけ作り、
下位ビューには .environmentObject() で渡すのが正解です。

🟢 修正版コード
🔹 HomeView.swift

struct HomeView: View {
    @State var selectedTab = 1
    @StateObject var ListVM = ListViewModel()
    var body: some View {
        TabView(selection: $selectedTab) {
            NavigationStack {
                ListView()
                    .environmentObject(ListVM)
            }
            .tabItem {
                Label("リスト", systemImage: "list.bullet")
            }
            .tag(1)
            
            NavigationStack {
                ChartView()
                    .environmentObject(ListVM)
            }
            .tabItem {
                Label("グラフ", systemImage: "chart.pie.fill")
            }
            .tag(2)
        }
    }
}

🔹 ListView.swiftと🔹 ChartView.swiftで

    @EnvironmentObject var ListVM: ListViewModel

🎉 修正後の挙動
✅ タスクをチェックした瞬間にグラフも自動更新
✅ 削除や追加もリアルタイム反映
✅ TabView間でデータが完全に同期
SwiftUIの @EnvironmentObject を使うことで、
複数のビューで同じViewModelを安全に共有できるようになりました。

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?