3 ms·
What I find crazy in this context, is the following: struct ToggleExample: View { @State private var isWarningEnabled = false var body: so
by bartvk 5y ago
What I find crazy in this context, is the following:
struct ToggleExample: View {
@State private var isWarningEnabled = false
var body: some View {
VStack {
Text("Hello, world!")
.foregroundColor(self.isWarningEnabled ? .red : .primary)
Button(action: { self.isWarningEnabled.toggle() }, label: {
Text("Hit me to toggle")
})
}
}
}
As you notice, the button action is a closure. In this case, a single line. Thus, I would expect that the following shorter code would work:
Button(action: self.isWarningEnabled.toggle) {
Text("Hit me to toggle")
}
That fails however with the following error message:
Partial application of 'mutating' method is not allowed
In a sense, this is logical. The `toggle()` is `mutating` and if we'd be able to save it as a closure, then we could run it from anywhere. That's like a reference value, when we're actually talking about a struct. But with SwiftUI, we're already in this gray area.
- tempodox 5y agoI think you misunderstood. The `action` closure is invoked with no arguments, but the invocation `self.isWarningEnabled.toggle()` does pass one argument, namely the `self` value from the closure's lexical context (`.toggle()` needs to know which instance to manipulate). If you replace the no-argument closure with a function that expects one argument (`self.isWarningEnabled.toggle`), you get the partial application the error mentions (“partial application” is passing fewer arguments to a function than it expects).
- bartvk 5y agoAha, of course... much appreciated, the penny dropped!
- willyt 5y agoI don’t write swift, but didn’t you miss a comma and a label for your Text(“Hit me to toggle”) argument in your second example? Did you mean: Button(action: self.isWarningEnabled.toggle, label:{ Text("Hit me to toggle") }) Not sure if you can just pass the method signature and omit the parentheses so it doesn’t get called like you can in python. Would be interested to know.
- deergomoo 5y ago> I don’t write swift, but didn’t you miss a comma and a label Swift has a feature called "trailing closures". If the last argument to a function is a closure, you can close the brackets early and put the closure directly after.