Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to return a Button from a function in SwiftUI?

I need to dynamically create a Button based on some parameters

func buildButton(parameter : Parameter) -> Button {
        switch (parameter){
            case Parameter.Value1:
                return Button(
                    action: {
                        ...
                },
                    label: {
                        ...
                }
            )
            case Parameter.Value2:
                return Button(
                    action: {...},
                    label: {
                        ...
                }
            )
        }
    }

But the compiler gives me this error:

Reference to generic type 'Button' requires arguments in <...>. Insert '<<#Label: View#>>'

So if I click Fix, the function declaration becomes

func buildButton(parameter : Parameter) -> Button<Label:View>

and the compiler gives

Use of undeclared type '<#Label: View#>'

What do I need to insert here to be able to return a Button?

like image 894
riciloma Avatar asked Aug 02 '19 08:08

riciloma


People also ask

Can you return a function in Swift?

Every function in Swift has a type, consisting of the function's parameter types and return type. You can use this type like any other type in Swift, which makes it easy to pass functions as parameters to other functions, and to return functions from functions.

How do I programmatically click a button in SwiftUI?

For example: you can run actionOfButton() from the place you want programmatically tap the Button, it would work the same.

How do I code a button in SwiftUI?

SwiftUI's button is similar to UIButton , except it's more flexible in terms of what content it shows and it uses a closure for its action rather than the old target/action system. To create a button with a string title you would start with code like this: Button("Button title") { print("Button tapped!") }

How do I pass a function in SwiftUI?

To pass a function as a parameter into another function in Swift, the accepted parameter type needs to describe a function. Now you can call this function by passing it an argument that is any function that takes two doubles and returns a double. This is the quick answer.


2 Answers

I'm not sure how important it is that you get a Button, but if you just need it to be displayed in another SwiftUI View without further refinements, you can just return some View. You only have to embed all your Buttons in AnyView's.

func buildButton(parameter : Parameter) -> some View {
        switch (parameter){
            case Parameter.Value1:
                return AnyView(Button(
                    action: {
                        ...
                },
                    label: {
                        ...
                })
            )
            case Parameter.Value2:
                return AnyView(Button(
                    action: {...},
                    label: {
                        ...
                })
            )
        }
    }
like image 113
thisIsTheFoxe Avatar answered Sep 21 '22 17:09

thisIsTheFoxe


If you look at the declaration of Button, you can see that it is a generic struct, so you need to supply its generic type parameter.

struct Button<Label> where Label : View

Make sure that you replace YourView with the actual type implementing View that you want to return.

class YourView: View { ... }

func buildButton(parameter : Parameter) -> Button<YourView> {
    switch (parameter){
        case Parameter.Value1:
            return Button(
                action: {
                    ...
            },
                label: {
                    ...
            }
        )
        case Parameter.Value2:
            return Button(
                action: {...},
                label: {
                    ...
            }
        )
    }
}
like image 23
Dávid Pásztor Avatar answered Sep 18 '22 17:09

Dávid Pásztor