为什么几何阅读器不将其孩子居中?

ami*_*abi 4 swift swiftui geometryreader

红色边框是几何区域,黑色边框是文本区域

目前使用 Xcode12 Beta 3

struct Testing_Geometry_: View {
    var body: some View {
        GeometryReader { geo in
            Text("Hello, World!")
                .border(Color.black)
        }
        .border(Color.red)
    }
}
Run Code Online (Sandbox Code Playgroud)

我想使用此代码将文本置于中心位置

struct Testing_Geometry_: View {
    var body: some View {
        GeometryReader { geo in
            Text("Hello, World!")
                .position(x:geo.frame(in:.global).midX,y:geo.frame(in:.global).midY)
                .border(Color.black)
        }
        .border(Color.red)
    }
}
Run Code Online (Sandbox Code Playgroud)

但我得到了这个结果,这意味着 Text 占用了整个几何尺寸,我认为这是不正确的!因为文本必须适合它们的空间

@twostraws 为布局系统建议的三个角色是

1- 父母提供其大小

2-child 选择它的大小

3-parent 定位其孩子

但我认为这是不对的!

文字占据了整个几何空间

gre*_*nge 7

如果有人正在寻找基本解决方案,您可以将其放入 Stack 之一,并使其使用具有对齐中心的几何尺寸的整体尺寸。这将使下面的所有元素使用正确的大小并在中心对齐

GeometryReader { geometry in
    ZStack {
        // ... some of your views
    }
    .frame(width: geometry.size.width, height: geometry.size.height, alignment: .center)
}
Run Code Online (Sandbox Code Playgroud)


Jes*_*urn 1

问题在于修饰符顺序很重要,因为修饰符实际上创建父视图。我使用背景而不是边框​​,因为我认为它们更容易看到。考虑这个与您的代码相同但仅使用背景的代码:

struct TestingGeometryView: View {
    var body: some View {
        GeometryReader { geo in
            Text("Hello, World!")
                .position(x:geo.frame(in:.global).midX,y:geo.frame(in:.global).midY)
                .background(Color.gray)
        }
        .background(Color.red)
    }
}
Run Code Online (Sandbox Code Playgroud)

这给出了以下内容:

Xcode 预览

由此您会想“文本采用了整个几何尺寸,我认为这是不正确的!” 因为灰色背景占据了整个屏幕,而不是仅围绕文本。同样,问题是修饰符顺序 - 背景(或示例中的边框)是父视图,但您将其设为“位置”视图而不是文本视图的父视图。为了使位置执行其操作,它需要整个可用的父空间(在本例中为整个屏幕减去安全区域)。因此,将背景或边框作为位置的父级意味着它们将占据整个屏幕。

让我们将顺序切换到此,以便背景视图仅适用于文本视图,并且我们可以看到文本视图的大小:

struct TestingGeometryView: View {
    var body: some View {
        GeometryReader { geo in
            Text("Hello, World!")
                .background(Color.gray)
                .position(x:geo.frame(in:.global).midX,y:geo.frame(in:.global).midY)
        }
        .background(Color.red)
    }
}
Run Code Online (Sandbox Code Playgroud)

这给出了我认为您所期望的结果,文本视图仅占用所需的最小大小,并遵循@twostraws 很好地解释的规则。

Xcode 预览如预期

这就是修饰符顺序如此重要的原因。很明显,GeometryReader 视图占据了整个屏幕,而 Text 视图仅占据了它所需的空间。在您的示例中,文本视图仍然只占用所需的空间,但您的边框位于位置视图周围,而不是文本视图周围。希望很清楚:-)