我正在尝试编写一个视图扩展,ViewModifier
它允许我将任何视图定位在CoordinateSpace
另一个视图中。到目前为止,我的代码确实有效,但如果 CoordinateSpaces 之一具有安全区域,它会出现对齐问题。我可以通过添加.edgesIgnoringSafeArea(.all)
到目标来修复它,CoordinateSpace
但我想使用这个扩展而不必担心其他坐标系统的安全区域。
澄清我的代码:
在我的代码中,第一个圆圈在 a 内HStack
,GeometryReader
并且设置了一个CoordinateSpace
被调用的"otherSpace"
。另一个 HStack 中的圆圈根据 中的位置设置其位置"otherSpace"
。第一个HStack
并且GeometryReader
在顶部,并且有edgeInset
20 个顶部。第二个没有。查看GeometryProxy
(中ViewModifier
)给我的值,我找不到一种方法来确定是否有一种方法来计算边缘插入。
到目前为止,这是我的代码:
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
HStack {
GeometryReader() { geometryProxy in
Circle()
.stroke(lineWidth: 3)
.fill(Color.blue)
.frame(width: 100, height: 100, alignment: .center)
.coordinateSpace(name: "otherSpace")
.position(CGPoint(x: 100, y: 100))
.edgesIgnoringSafeArea(.all) //I'd like a way not to use this.
.onAppear() {
}
}.background(Color.green)
}
HStack {
Circle()
.foregroundColor(.red)
.frame(width: 100, height: 100, alignment: .center)
.position(CGPoint(x: 100, y: 100), in: .named("otherSpace"))
}
}
}
}
extension View {
func position(_ position: CGPoint, in coordinateSpace: CoordinateSpace) -> some View {
ModifiedContent(content: self, modifier: AbsolutePosition(position: position, coordinateSpace: coordinateSpace))
}
}
struct AbsolutePosition: ViewModifier {
@State var position: CGPoint
let coordinateSpace: CoordinateSpace
@State var localPosition: CGPoint = .zero
@State var targetPosition: CGPoint = .zero
func body(content: Content) -> some View {
GeometryReader { geometry in
content.onAppear() {
localPosition = geometry.frame(in: .local).origin
targetPosition = geometry.frame(in: coordinateSpace).origin
position.x = localPosition.x - targetPosition.x + position.x
position.y = localPosition.y - targetPosition.y + position.y
}.position(position)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
更新图像。
第一张图片显示了.edgesIgnoringSafeArea(.all)
在目标圆上使用时的结果。无论目标圆(CoordinateSpace)是否有安全区域,我都想得到这个结果。但是当我删除时,.edgesIgnoringSafeArea(.all)
我得到了第二张图像,因为我的扩展不知道是否有安全区域,并且总是计算好像没有安全区域。