0

Is it technically possible to call a method from a view after getting the confirmation from the subview ? I could call it from the SubStruct if I pass the viewModel and item to it, but I am just curious about the code below which results in

Segmentation Fault: 11

import SwiftUI

struct ContentView: View {
    var body: some View {
        MainStruct(viewModel: MyViewModel())
    }
}

struct MainStruct: View {
    @StateObject var viewModel: MyViewModel
    @State var functionToPass: ()
    
    let items = ["test1", "test2", "test2"]
    
    var body: some View {
        ForEach(items, id: \.self) { (item) in
            Text(item).onTapGesture {
                functionToPass = viewModel.deleteItem(name: item)
            }
        }
        
        SubStruct(passedFunction: {functionToPass})
    }
    
    struct SubStruct: View {
        var passedFunction: () -> Void
        
        var body: some View {
            Button(action: {passedFunction()}, label: {
                Text("confirm deletion")
            })
        }
    }
    
}

class MyViewModel: ObservableObject {
    func deleteItem(name: String) {
        print(name)
        ///deletion logic
    }
}

1 Answer 1

1

Try this :

struct MainStruct: View {
    @StateObject var viewModel: MyViewModel
    @State private var functionToPass: () -> Void = {}

    let items = ["test1", "test2", "test2"]

    var body: some View {
        VStack {
            ForEach(items, id: \.self) { item in
                Text(item)
                    .onTapGesture {
                        functionToPass = {
                            viewModel.deleteItem(name: item)
                        }
                    }
            }
            SubStruct(passedFunction: functionToPass)
        }
    }

    struct SubStruct: View {
        var passedFunction: () -> Void

        var body: some View {
            Button(action: {
                passedFunction()
            }, label: {
                Text("confirm deletion")
            })
        }
    }
}

Sign up to request clarification or add additional context in comments.

2 Comments

thanks, it is working ! could you explain briefly what the actual problem was ? wrong type in the @State var declaration ?
You declared your functionToPass as Void and I guess you wanted a closure that takes no argument and returns Void so () -> Void. A State need an initial value, here an empty closure : {}. On tap gesture : you tried to assign the result of your function (Void) to your parameter. But you have to assign to it a closure that will execute your function (deleteItem). To SubStruct you can pass functionToPass directly as an argument (no need of {}). And you could do the same with Button : action: passedFunction

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.