I’ve an issue with ButtonStyle’s perform makeBody
triggers PreferenceKey cut back
perform, if I’ve swap
or if
assertion inside makeBody
.
I’ve a code beneath:
struct TestPreferenceKey: PreferenceKey {
static var defaultValue: Int = 0
static func cut back(worth: inout Int, nextValue: () -> Int) {
print("cut back worth:", worth)
print("cut back nextValue:", nextValue())
worth = nextValue()
}
}
struct TestButtonStyle: ButtonStyle {
enum `Kind` {
case a
case b
}
let kind: `Kind`
func makeBody(configuration: Configuration) -> some View {
swap kind {
case .a:
configuration.label
case .b:
configuration.label
}
}
}
struct ButtonView: View {
var physique: some View {
Button {
} label: {
Textual content("Button")
}
.buttonStyle(TestButtonStyle(kind: .a))
}
}
struct ContentView: View {
var physique: some View {
VStack {
ButtonView()
ButtonView()
}
.onPreferenceChange(TestPreferenceKey.self) { worth in
print("worth:", worth)
}
}
}
And I’ve the subsequent prints in log:
cut back worth: 0
cut back nextValue: 0
worth: 0
As I perceive how PreferenceKey
works, I ought to don’t have anything printed out.
And it really works so, if I name completely different perform from ButtonStyle’s makeBody
:
struct TestButtonStyle: ButtonStyle {
enum `Kind` {
case a
case b
}
let kind: `Kind`
func makeBody(configuration: Configuration) -> some View {
switcher(configuration: configuration)
}
func switcher(configuration: Configuration) -> some View {
swap kind {
case .a:
configuration.label
case .b:
configuration.label
}
}
}
Now, I’ve nothing printed out.
However, if I add @ViewBuilder
wrapper to switcher
perform, I’ve printed out once more:
...
@ViewBuilder
func switcher(configuration: Configuration) -> some View {
swap kind {
case .a:
configuration.label
case .b:
configuration.label
}
}
cut back worth: 0
cut back nextValue: 0
worth: 0
Is it anticipated habits with ViewBuilder
? Or is it a bug?
Is it all the time essential to do such a traversal with an extra perform?
If anybody is aware of the reply, it will be a lot appreciated! I’d additionally be pleased about helpful hyperlinks on the subject!
UDP:
If I add .desire for certainly one of Views, I get a incorrect results of TestPreferenceKey worth:
...
var physique: some View {
VStack {
ButtonView()
.desire(
key: TestPreferenceKey.self,
worth: 3
)
ButtonView()
}
.onPreferenceChange(TestPreferenceKey.self) { worth in
print("worth:", worth)
}
}
Result’s:
cut back worth: 3
cut back nextValue: 0
worth: 0
Though the TestPreferenceKey worth must be 3.
After all, with out @ViewBuilder
on switcher
TestPreferenceKey worth is true – 3
Printed out:
worth: 3