質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

3回答

1310閲覧

SwiftUIでのToggleの切り替え

kazu_116

総合スコア22

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2022/01/21 01:26

ViewにToggleを配置しました。
Viewは、ViewModelからModelのisToggleの値の変更を取得し、
Toggleのオンオフを切り替えようとしています。

しかし、下記の実装ではToggleはクリックしても初期値のtrueから変更されません。
(.constant()は定数を示しているので値が変化していないようです。)

MVVMを意識した記述をする場合、どのように記述すべきでしょうか?
ご教授お願いいたします。

View

1import SwiftUI 2 3struct ContentView: View { 4 @ObservedObject var viewModel: ViewModel = ViewModel() 5 var body: some View { 6 Toggle("hogehoge", isOn: .constant(viewModel.isToggle)) 7 .padding() 8 } 9} 10 11struct ContentView_Previews: PreviewProvider { 12 static var previews: some View { 13 ContentView() 14 } 15}

ViewModel

1import Foundation 2import SwiftUI 3 4class ViewModel: ObservableObject { 5 @Published var model: Model = Model() 6 7 var isToggle: Bool { 8 return model.isToggle 9 } 10}d

Model

1import Foundation 2 3struct Model { 4 var isToggle: Bool = true 5}

環境

  • macOS : 11.6
  • Xcode : 13.2.1

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Tomato45

2022/01/21 02:33

@State varでもつくって、ZStackか何かにコードを入れた後、onAppearを使って、viewModelのisToggleを値を@State varを入れてはどうでしょうか?
Tomato45

2022/01/21 02:50

または「onChange」。
guest

回答3

0

Tomato45さん

回答ありがとうございます。

指摘しただいた通りViewに
@State private var isToggle: Bool = true
を追加してonchangeを使ってViewModelに記述したchangeToggleを呼ぶようにしてみました。

View

1import SwiftUI 2 3struct ContentView: View { 4 @StateObject var viewModel: ViewModel = ViewModel() 5 @State private var isToggle: Bool = true 6 var body: some View { 7 ZStack { 8 Toggle("hogehoge", isOn: $isToggle) 9 .padding() 10 } 11 .onChange(of: isToggle) { 12 newValue in viewModel.changeToggle() 13 } 14 } 15} 16 17struct ContentView_Previews: PreviewProvider { 18 static var previews: some View { 19 ContentView() 20 } 21}

ViewModel

1import Foundation 2import SwiftUI 3 4class ViewModel: ObservableObject { 5 @Published var model: Model = Model() 6 7 var isToggle: Bool { 8 return model.isToggle 9 } 10 11 func changeToggle() { 12 model.changeToggle() 13 } 14}

Model

1import Foundation 2 3struct Model { 4 var isToggle: Bool = true 5 6 mutating func changeToggle () { 7 isToggle.toggle() 8 } 9}

投稿2022/01/21 06:02

kazu_116

総合スコア22

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

自己解決

zundaaさん

回答ありがとうございます。

Toggle("hogehoge", isOn: .constant(viewModel.isToggle))ではなく
Toggle("hogehoge", isOn: $viewModel.isToggle)で動くはずです。

ViewModelのisToggleがgetterのみなので下記のエラーが生じます。
Cannot assign to property: 'isToggle' is a get-only property

単純にsetterも記述すればよいのでしょうか?

投稿2022/01/21 05:49

kazu_116

総合スコア22

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

Toggle("hogehoge", isOn: .constant(viewModel.isToggle))ではなく
Toggle("hogehoge", isOn: $viewModel.isToggle)で動くはずです。

関係ないですが、ObservedObjectではなくたいていの場合は、StateObjectのほうがよかったりします。
https://tokizuoh.dev/posts/td152tqrb7iflicp/

投稿2022/01/21 05:20

zundaa

総合スコア101

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kazu_116

2022/01/21 05:54

zundaaさん 回答ありがとうございます。 Toggle("hogehoge", isOn: .constant(viewModel.isToggle))ではなく Toggle("hogehoge", isOn: $viewModel.isToggle)で動くはずです。 ViewModelのisToggleがgetterのみなので下記のエラーが生じます。 Cannot assign to property: 'isToggle' is a get-only property 単純にsetterも記述すればよいのでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問