我想从ContentView中构建一个独立的函数,可以使用此func初始化一些值,例如在此向下代码中,我希望使用该函数获取View的大小,但是由于我的未知原因,它返回零,我认为背景修改不符合我在此版本中的要求。有什么帮助吗?
func viewSizeReaderFunction<Content: View>(content: Content) -> CGSize {
var sizeOfView: CGSize = CGSize()
content
.background(
GeometryReader { geometry in
Color
.clear
.onAppear() { sizeOfView = geometry.size }
})
return sizeOfView
}
let sizeOfText: CGSize = viewSizeReaderFunction(content: Text("Hello, world!"))
struct ContentView: View {
var body: some View {
Color.red
.onAppear() {
print(sizeOfText)
}
}
}
一般的想法是使视图使用来报告其大小preference
,并创建一个视图修饰符以捕获该大小。但是,就像@RobNapier所说的那样,该结构必须在视图层次结构中,并且因此在呈现上下文中,才能讨论大小。
struct SizeReporter: ViewModifier {
@Binding var size: CGSize
func body(content: Content) -> some View {
content
.background(GeometryReader { geo in
Color.clear
.preference(key: SizePreferenceKey.self, value: geo.size)
})
.onPreferenceChange(SizePreferenceKey.self, perform: { value in
size = value
}
}
}
而且我们需要定义SizePreferenceKey
:
extension SizeReporter {
private struct SizePreferenceKey: PreferenceKey {
static let defaultValue: CGSize = .zero
static func reduce(value: inout CGSize, nextValue: () -> CGSize) {
value = nextValue()
}
}
}
您可以在上创建一个便捷方法View
:
extension View {
func getSize(_ size: Binding<CGSize>) -> some View {
self.modifier(SizeReporter(size: size))
}
}
并像这样使用它:
@State var size: CGSize = .zero
var body: some View {
Text("hello").getSize($size)
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句