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
?
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.
For example: you can run actionOfButton() from the place you want programmatically tap the Button, it would work the same.
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!") }
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.
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: {
...
})
)
}
}
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: {
...
}
)
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With