FWIW, I think that the API of the Button
initializer may fall into the camp of "would have been designed differently in Swift 5.3" as @beccadax notes re: sheet
here. Using the same transformation that Brent does for sheet
, the API might have been designed as:
// Declared as
init(label: () -> Label, action: @escaping () -> Void)
// Called as
Button {
Text("My button")
} action: {
print("Tapped")
}.modifier()
// Or...
Button
.init {
Text("My button")
}
action: {
print("Tapped")
}
.modifier()
I actually prefer the existing Button
API and would advocate for its current design (as well as that of sheet
) even in light of SE-0279, since it has the important property that all @ViewBuilder
closures come at the end of the parameter list.
Specifically in the SwiftUI context (though the logic extends to other eDSL contexts as well), my preferred approach is to place only the @ViewBuilder
closures in trailing position and move imperative code out-of-line. Thus, the 'ideal' for me is actually:
Button(action: self.buttonTapped) {
Text("My button")
}
IMHO, mixing eDSL closures indiscriminately with 'normal' closures, especially in trailing position) is bound to cause readability difficulties, regardless of what labels you apply at the call site.