SwiftUI:@状态已修改,但在读取后面的行时似乎没有变化



我正试图在SwiftUI中构建一个按钮样式,我想使用首选项技术来检索配置标签的大小,如本文所述。

但我有一个奇怪的问题,我在onPreferenceChange中的代码本应更改我的size属性,但却没有更改它。你会在示例代码中看到这一点,但我设置了新值,以及打印@State属性后的行,但我没有得到我刚刚设置的值!

import SwiftUI
struct MajorButtonStyle: ButtonStyle {

@State private var labelSize: CGSize = .zero

func makeBody(configuration: Configuration) -> some View {
RoundedRectangle(cornerRadius: 10, style: .continuous)
.fill(Color.accentColor)
.overlay(
configuration.label
.foregroundColor(.white)
.padding()
.modifier(SizeModifier())
.onPreferenceChange(SizePreferenceKey.self) { value in
print("PREFERENCE HAS CHANGED!!!!!")
print(value)
self.labelSize = value
print(value.height)
print(self.labelSize.height)
}
)
.frame(height: labelSize.height)
}

}
// MARK: Modifier and preference key
struct SizePreferenceKey: PreferenceKey {
static var defaultValue: CGSize = .zero
static func reduce(value: inout CGSize, nextValue: () -> CGSize) {
value = nextValue()
}
}
struct SizeModifier: ViewModifier {
private var sizeView: some View {
GeometryReader { geometry in
Color.clear.preference(key: SizePreferenceKey.self, value: geometry.size)
}
}
func body(content: Content) -> some View {
content.background(sizeView)
}
}

运行应用程序并实例化一个按钮,下面是控制台输出:

PREFERENCE HAS CHANGED!!!!!
(89.0, 52.33333333333333)
52.33333333333333
0.0 // 😫

有人能告诉我我是否遗漏了什么吗?或者,如果我陷入了某种奇怪的边缘案例或bug?我正在Xcode 12测试版2上测试这个。

提前谢谢。

您尝试做的事情可以用更简单的方法实现

struct MajorButtonStyle: ButtonStyle {
func makeBody(configuration: Configuration) -> some View {
configuration.label
.frame(maxWidth: .infinity)    // << for all available width !!
.foregroundColor(.white)
.padding()
.background(
RoundedRectangle(cornerRadius: 10, style: .continuous)
.fill(Color.accentColor)
)
}
}

注意:顺便说一句,State包装器仅在View中工作,但ButtonStyle不是视图

最新更新