我正在尝试使用 anchorPreference
在我的 VStack 中的某个 View 上绘制叠加层。
但是,它仅适用于最简单的情况。当我的 VStack 的内容变得有点复杂时,从不绘制叠加层。
这是我的代码
struct debug_test: View {
@State private var someState = false
var body: some View {
VStack {
Text("Hello World !!!")
.anchorPreference(
key: BoundsPreferenceKey.self,
value: .bounds
) { $0 }
//////////////////////////////////////////////////////////
// When I remove below lines - it works ok.
// But when I put add some conditionally-visible view and one more view
// it stops drawing an overlay.
// Apparently, `preferences` is always nil in that case.
if someState {
Text("Pooop")
}
Text("Pooop2")
//////////////////////////////////////////////////////////
}
.overlayPreferenceValue(BoundsPreferenceKey.self) { preferences in
GeometryReader { geometry in
preferences.map {
Rectangle()
.stroke(Color.red, lineWidth: 5)
.frame(
width: geometry[$0].width,
height: geometry[$0].height
)
.offset(
x: geometry[$0].minX,
y: geometry[$0].minY
)
}
}
}
}
}
正如我在代码注释中所解释的那样,当我得到一个内部只有一个 View 的简单堆栈时,它工作正常。但是当我在里面添加更多 View 和一些条件时,它停止工作。
任何线索如何解决它?
最佳答案
首选项在布局期间更新,我假设您的首选项键保持不变 Anchor<CGRect>?
在布局结束时重置为零。
这是固定变体。使用 Xcode 11.4/iOS 13.4 测试。
注意:我建议为您的自定义首选项键使用显式结构模型。考虑 this solution for example
struct BoundsPreferenceKey: PreferenceKey {
static var defaultValue: [Anchor<CGRect>] = [] // << use something persistent
static func reduce(value: inout [Anchor<CGRect>], nextValue: () -> [Anchor<CGRect>]) {
value.append(contentsOf:nextValue())
}
}
struct debug_test: View {
@State private var someState = false
var body: some View {
VStack {
Text("Hello World !!!")
.anchorPreference(
key: BoundsPreferenceKey.self,
value: .bounds
) { [$0] }
if someState {
Text("Pooop")
}
Text("Pooop2")
//////////////////////////////////////////////////////////
}
.overlayPreferenceValue(BoundsPreferenceKey.self) { preferences in
GeometryReader { geometry in
preferences.map {
Rectangle()
.stroke(Color.red, lineWidth: 5)
.frame(
width: geometry[$0].width,
height: geometry[$0].height
)
.position( // << here is fix as well !!
x: geometry[$0].midX,
y: geometry[$0].midY
)
}[0] // << just for demo, this should be more safe !!
}
}
}
}
关于ios - SwiftUI View 首选项 : overlayPreferenceValue returns nil when used on complex containers,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62017158/