1

我有一个简单的用例,有一个动态数量的文本的 VStack,其中切换按钮来自一个数组。

import SwiftUI

public struct Test: View {
        
    @ObservedObject public var viewModel = TestViewModel()
    
    public init() {
        
    }
    
    public var body: some View {
        VStack {
            ForEach(viewModel.models) { model in
                ToggleView(title: <#T##Binding<String>#>, switchState: <#T##Binding<Bool>#>)
                //how to add the above
            }
            
        }.padding(50)
    }
}

struct ToggleView: View {
    
    @Binding var title: String
    @Binding var switchState: Bool
    
    var body: some View {
        VStack {
            Toggle(isOn: $switchState) {
                Text(title)
            }
        }
    }
}

public class TestModel: Identifiable {
    
    @Published var state: Bool {
        didSet {
            //do something
            //publish to the view that the state has changed
        }
    }
    @Published var title: String
    
    init(state: Bool, title: String) {
        self.state = state
        self.title = title
    }
}

public class TestViewModel: ObservableObject {
    
    @Published var models: [TestModel] = [TestModel(state: false, title: "Title 1"), TestModel(state: true, title: "Title 2")]
   
}

出现以下问题:

  1. 在 MVVM 模式中,绑定变量可以放在模型类中还是应该放在视图模型中?
  2. 当切换状态发生变化时,如何将状态变化的消息从模型类发送到视图/场景?
  3. 如果在视图模型中为每个切换状态使用绑定变量数组,如何知道数组的哪个特定元素已更改?(见下面的代码片段)
class ViewModel {

    @Published var dataModel: [TestModel]


    @Published var toggleStates = [Bool]() {
        didSet {
            //do something based on which element of the toggle states array has changed
        }
    }
}

请帮忙解答以上问题。

4

1 回答 1

0

这是您实现愿望的一种方法。有没有你会注意到你必须使用@ObservedObject. 诀窍是使用索引来达到您绑定的数组元素。如果model直接在数组元素上循环,则会失去底层绑定属性。

struct Test: View {

@ObservedObject public var viewModel = TestViewModel()

var body: some View {
    VStack {
        
        ForEach(viewModel.models.indices) { index in
            ToggleView(title: self.viewModel.models[index].title, switchState:  self.$viewModel.models[index].state)
        }
        
    }.padding(50)
  }
}

class TestViewModel: ObservableObject {
    @Published var models: [TestModel] = [
        TestModel(state: false, title: "Title 1"),
        TestModel(state: true, title: "Title 2")]
}


struct ToggleView: View {

    var title: String
    @Binding var switchState: Bool

    var body: some View {
        VStack {
            Toggle(isOn: $switchState) {
                Text(title)
        }
      }
   }
}

class TestModel: Identifiable {

    var state: Bool
    var title: String

    init(state: Bool, title: String) {
        self.title = title
        self.state = state
    }
}

希望这对你有用。

最好的

于 2020-09-20T10:35:57.873 回答