today-is-a-good-day
HomeiOS Developmentios - How do I modify ViewModel data from button in swiftui

ios – How do I modify ViewModel data from button in swiftui


It seems I am entirely loosing a concept of MVVM data flow:
I have a simple example view, displaying array of Doc items, supplied by ViewModel class that has to be a singleton, accessed from multiple places.
Each item has name and a button, that should change it’s “isFav” value, and reflect the change through color change of the said button.

I tried changing it via vm function, via struct mutating func, the direct way, but each one I come up with gives me a different error.
What am I doing wrong?

import SwiftUI

struct Doc: Identifiable
{
    let id: UUID
    var name: String
    var isFav: Bool = false
    
    init(_ name: String)
    {
        self.id = UUID()
        self.name = name
    }
    
    init()
    {
        self.id = UUID()
        self.name = id.uuidString.dropLast(13).lowercased()
    }
    
    mutating func updateIsFav()
    {
        self.isFav.toggle()
    }
}

class ViewModel: ObservableObject
{
    static var shared = ViewModel()
    
    private init() {}
    @Published var array: [Doc] = []

    func updateIsFav(for doc: Doc)
    {
        if let index = array.firstIndex(where: { $0.id == doc.id} )
        {
            self.array[index].isFav.toggle()
        }
    }
}

struct ContentView: View
{    
    @ObservedObject var model = ViewModel.shared
    var body: some View
    {
        ZStack
        {
            Color.black.ignoresSafeArea()
            ScrollView
            {
                VStack
                {
                    ForEach( model.array, id: \.id )
                    {
                        doc in
                        HStack
                        {
                            Text( doc.name )
                                .foregroundColor(.white)
                            
                            Button(action:
                                    {
                                        doc.updateIsFav()           // Cannot use mutating member on immutable value: 'doc' is a 'let' constant
                                        doc.isFav.toggle            // Cannot reference 'mutating' method as function value
                                        model.updateisFav(for: doc) // Cannot call value of non-function type 'Binding<Subject>'
                                    },
                                   label:
                                    {
                                            Image(systemName: "star")
                                        .foregroundColor(doc.isFav ? .yellow : .white)
                                    }
                            )
                           

                        }
                    }
                }
            }
        }
        .onAppear()
        {
            model.array.append(Doc())
            model.array.append(Doc())
            model.array.append(Doc())
            model.array.append(Doc())
            model.array.append(Doc())
            model.array.append(Doc())
            model.array.append(Doc())
        }
        
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View 
    {
        ContentView()
            .previewDevice("iPhone 13")
    }
}

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

- Advertisment -
Google search engine

Most Popular

Recent Comments