SwiftUI 中 MVVM 模式中多个切换的绑定变量数组

Posted

技术标签:

【中文标题】SwiftUI 中 MVVM 模式中多个切换的绑定变量数组【英文标题】:Array of binding variables for multiple toggles in MVVM pattern in SwiftUI 【发布时间】:2020-07-02 04:10:24 【问题描述】:

我有一个简单的用例,它有一个动态数量的文本的 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")]
   


出现以下问题:

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

    @Published var dataModel: [TestModel]


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

请帮忙解答以上问题。

【问题讨论】:

【参考方案1】:

这里有一种方法可以实现您的愿望。 您是否会注意到您必须使用@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
    

希望这对你有用。

最好的

【讨论】:

以上是关于SwiftUI 中 MVVM 模式中多个切换的绑定变量数组的主要内容,如果未能解决你的问题,请参考以下文章

手动更新 SwiftUI View

将 SwiftUI 按钮绑定到 AnySubscriber,例如 RxCocoa 的按钮点击

导航 MVVM

如何在 SwiftUI 中实现 MVVM 模式?视图不会重新渲染

如何将 SwiftUI 视图绑定到数组中元素的属性

MVVM模式下 DataTemplate 中控件的绑定