Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to bind objects using MVVM design pattern?

I'm trying to change below code(1.) to MVVM architecture(2.) but can't figure out how to bind objects.

I think the problem is FirstView only pass value but not actually a Binding Object, I tried some different ways but always stuck on don't know how to assign Binding Object to @Published.

Could somebody please give a few hints?

  1. (Works fine)
struct FirstView: View {
    @State var showSecondView = false

    var body: some View {
        Button(action: {
            self.showSecondView.toggle()
        }) {
            Text("Show second view")
        }
        .sheet(isPresented: $showSecondView) {
            SecondView(showSecondView: self.$showSecondView)
        }
    }
}
struct SecondView: View {
    @Binding var showSecondView: Bool

    var body: some View {
        Button(action: {
            self.showSecondView.toggle()
        }) {
            Text("Dismiss")
        }
    }
}
  1. (MVVM)
struct FirstView: View {
    @ObservedObject var vm = FirstViewModel()

    var body: some View {
        Button(action: {
            self.vm.showSecondView.toggle()
        }) {
            Text("Show second view")
        }
        .sheet(isPresented: $vm.showSecondView) {
            SecondView2(vm: SecondViewModel(showSecondView: self.vm.showSecondView))
        }
    }
}

class FirstViewModel: ObservableObject {
    @Published var showSecondView = false
}
struct SecondView: View {
    @ObservedObject var vm: SecondViewModel

    var body: some View {
        Button(action: {
            self.vm.showSecondView.toggle()
        }) {
            Text("Dismiss")
        }
    }
}

class SecondViewModel: ObservableObject {
    @Published var showSecondView: Bool

    //Right here, i'm not sure how to bind 'showSecondView' from FirstView
    init(showSecondView: Bool) {
        self.showSecondView = showSecondView
    }
}
like image 995
raxabizze Avatar asked Jan 27 '26 00:01

raxabizze


1 Answers

You can pass directly the Binding<Bool> to the second VM but in this way, there's no need to have @Published var and it also doesn't need to be ObservableObject and marked as @ObservedObject. There might be a better solution to this.

struct FirstView: View {
    @ObservedObject var vm = FirstViewModel()

    var body: some View {
        Button(action: {
            self.vm.showSecondView.toggle()
        }) {
            Text("Show second view")
        }
        .sheet(isPresented: $vm.showSecondView) {
            SecondView(vm: SecondViewModel(showSecondView: self.$vm.showSecondView))
        }
    }
}

class FirstViewModel: ObservableObject {
    @Published var showSecondView = false
}

struct SecondView: View {
    var vm: SecondViewModel

    var body: some View {
        Button(action: {
            self.vm.showSecondView.wrappedValue.toggle()
        }) {
            Text("Dismiss")
        }
    }
}

class SecondViewModel {
    var showSecondView: Binding<Bool>

    init(showSecondView: Binding<Bool>) {
        self.showSecondView = showSecondView
    }
}
like image 67
Fabio Felici Avatar answered Jan 29 '26 13:01

Fabio Felici