Arrays @在多个ViewModels中发布的阵列-SwiftUI

Arrays @在多个ViewModels中发布的阵列-SwiftUI,arrays,swiftui,viewmodel,shared,Arrays,Swiftui,Viewmodel,Shared,我的应用程序只有两个视图,两个视图都有自己的ViewModel。ViewA显示和操作selectedNumbers数组中的对象。ViewB拥有所有可用的对象(数字)-在此视图中,我希望操纵ViewA使用的selectedNumbers数组 我试图找出,如何在这两个视图模型之间共享这些SelectedNumber数组。我试着使用EnvironmentObject、StaticObject等,但没有任何东西能满足我的需要。我应该使用什么方法来达到预期的结果。谢谢你的帮助 import SwiftUI

我的应用程序只有两个视图,两个视图都有自己的ViewModel。ViewA显示和操作selectedNumbers数组中的对象。ViewB拥有所有可用的对象(数字)-在此视图中,我希望操纵ViewA使用的selectedNumbers数组

我试图找出,如何在这两个视图模型之间共享这些SelectedNumber数组。我试着使用EnvironmentObject、StaticObject等,但没有任何东西能满足我的需要。我应该使用什么方法来达到预期的结果。谢谢你的帮助

import SwiftUI

struct ViewA: View {

    @ObservedObject var viewModel = ViewModelA()

    var body: some View {
        VStack {
            Text("\(viewModel.number)")
                .font(.largeTitle)
                .padding()
                .onTapGesture {
                    viewModel.showNext()
                }
            ViewB()
        }
    }
}

class ViewModelA: ObservableObject {
    var numbers: [Int] = []
    @Published var number: Int
    var index = 0

    init() {
        number = numbers.isEmpty ? 0 : numbers[index]
    }

    func showNext() {
        guard !numbers.isEmpty else { return }
        if index < numbers.count - 1 {
            index += 1
        } else {
            index = 0
        }
        number = numbers[index]
    }
}

struct ViewB: View {

    @ObservedObject var viewModel = ViewModelB()

    var body: some View {
        HStack {
            ForEach(viewModel.numbers, id: \.self) { number in
                Text("\(number)")
                    .foregroundColor(viewModel.selectedNumbers.contains(number) ? .red : .black)
                    .onTapGesture {
                        viewModel.updateSelection(number)
                    }
            }
        }
    }
}

class ViewModelB: ObservableObject {
    @Published var numbers: [Int] = []
    @Published var selectedNumbers: [Int] = []

    init() {
        numbers.append(contentsOf: [1,2,3,4,5,6,7,8])
    }

    func updateSelection(_ number: Int) {
        if selectedNumbers.contains(number) {
            selectedNumbers.remove(number)
        } else {
            selectedNumbers.append(number)
        }
    }
}

extension Array where Element: Equatable {
    mutating func remove(_ object: Element) {
        guard let index = firstIndex(of: object) else {return}
        remove(at: index)
    }
}
导入快捷界面
结构视图:视图{
@ObservedObject var viewModel=ViewModelA()
var body:一些观点{
VStack{
文本(“\(viewModel.number)”)
.font(.largeTitle)
.padding()
.ontapsigne{
viewModel.showNext()
}
ViewB()
}
}
}
类ViewModelA:ObservableObject{
变量编号:[Int]=[]
@已发布变量编号:Int
var指数=0
init(){
number=numbers.isEmpty?0:numbers[索引]
}
func showNext(){
守卫!number.isEmpty else{return}
如果索引
您仍然可以保持逻辑独立,但是您需要保持一个单一的真相来源,如果您想在视图之间共享数据,您需要传递
绑定
,或者您也可以在子视图之间共享
@ObservedObject

import SwiftUI


struct ViewA: View {

    @ObservedObject var viewModel = ViewModelA(modelB: ViewModelB())

    var body: some View {
        VStack {
            Text("\(viewModel.number)")
                .font(.largeTitle)
                .padding()
                .onTapGesture {
                    viewModel.showNext()
                }
            ViewB(model: viewModel)
        }
    }
}

class ViewModelA: ObservableObject {
    
    var numbers: [Int] = []
    
    @Published var number: Int
    @Published var modelB:ViewModelB
    
    var index = 0

    init(modelB:ViewModelB) {
        self.modelB = modelB
        number = numbers.isEmpty ? 0 : modelB.selectedNumbers[index]
    }

    func showNext() {
        guard !modelB.selectedNumbers.isEmpty else { return }
        if index < modelB.selectedNumbers.count - 1 {
            index += 1
        } else {
            index = 0
        }
        number = modelB.selectedNumbers[index]
    }
}

struct ViewB: View {

    @ObservedObject var model : ViewModelA

    var body: some View {
        HStack {
            ForEach(model.modelB.selectedNumbers, id: \.self) { number in
                Text("\(number)")
                    .foregroundColor(model.modelB.selectedNumbers.contains(number) ? .red : .black)
                    .onTapGesture {
                        model.modelB.updateSelection(number)
                    }
            }
        }
    }
}

struct ViewModelB {
    
    var selectedNumbers: [Int] = []

    init() {
        selectedNumbers.append(contentsOf: [1,2,3,4,5,6,7,8])
    }

   mutating func updateSelection(_ number: Int) {
        if selectedNumbers.contains(number) {
            selectedNumbers.remove(number)
        } else {
            selectedNumbers.append(number)
        }
    }
}

extension Array where Element: Equatable {
    mutating func remove(_ object: Element) {
        guard let index = firstIndex(of: object) else {return}
        remove(at: index)
    }
}
导入快捷界面
结构视图:视图{
@ObservedObject var viewModel=ViewModelA(modelB:ViewModelB())
var body:一些观点{
VStack{
文本(“\(viewModel.number)”)
.font(.largeTitle)
.padding()
.ontapsigne{
viewModel.showNext()
}
ViewB(模型:viewModel)
}
}
}
类ViewModelA:ObservableObject{
变量编号:[Int]=[]
@已发布变量编号:Int
@已发布的var模型B:ViewModelB
var指数=0
初始化(modelB:ViewModelB){
self.modelB=modelB
number=numbers.isEmpty?0:modelB.selectedNumbers[索引]
}
func showNext(){
guard!modelB.selectedNumbers.isEmpty else{return}
如果索引
您有两个不同的真相来源,您应该使用绑定重新考虑您的模型设计,并保留单一真相来源您的意思是什么?只使用一个ViewModel->ViewModelA并将其绑定到ViewB?我试图把这两种观点的逻辑分开。。