Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwiftUI how add custom modifier with callback

Tags:

ios

swift

swiftui

In SwiftUI you can wrote code like this:

List {
    ForEach(users, id: \.self) { user in
        Text(user)
    }
    .onDelete(perform: delete)
}

I try to add functionality with .onDelete syntax method to my custom component:

struct MyComponen: View {
    @Binding var alert: String

    .
    .
    .
}

I try to add this ability with extension:

extension MyComponent {

   func foo() -> Self { 
        var copy = self
        copy.alert = "Hohoho"
        return copy
    }

    func onDelete() -> Void { 

    }
}

How can I change state (or callback function with):

struct ContentView: View { 
    var body: some View {
        Group {
            MyComponent() //-> with alert = "state 1"
            MyComponent().foo() //-> with alert = "state 2"
            MyComponent().foo(action: actionFunction) //-> how do this?
        }
    } 
}
like image 882
Tim Avatar asked Nov 09 '19 14:11

Tim


People also ask

How do I create a custom modifier in SwiftUI?

To create a custom modifier, create a new struct that conforms to the ViewModifier protocol. This has only one requirement, which is a method called body that accepts whatever content it's being given to work with, and must return some View .

What is a callback in SwiftUI?

So callbacks are used as another way for one piece of code to communicate with another piece of code somewhere else in the app.

What is SwiftUI ViewModifier?

A modifier that you apply to a view or another view modifier, producing a different version of the original value.


1 Answers

Continuing your approach this might look like below. As alternate it is possible to use ViewModifier protocol.

struct MyComponen: View {
    @Binding var alert: String
    var action: (() -> Void)?
    var body: some View {
        VStack {
            Text("Alert: \(alert)")
            if nil != action {
                Button(action: action!) {
                    Text("Action")
                }
            }
        }
    }
}

extension MyComponen {

    func foo(perform action: @escaping () -> Void ) -> Self {
         var copy = self
         copy.action = action
         return copy
     }
}

struct TestCustomModifier: View {
    @State var message = "state 2"
    var body: some View {
        VStack {
            MyComponen(alert: .constant("state 1"))
            MyComponen(alert: $message).foo(perform: {
                print(">> got action")
            })
        }
    }
}

struct TestCustomModifier_Previews: PreviewProvider {
    static var previews: some View {
        TestCustomModifier()
    }
}

backup

like image 52
Asperi Avatar answered Oct 02 '22 04:10

Asperi