为什么几何读取器不使子对象居中?

时间:2020-07-26 12:51:52

标签: swift swiftui geometryreader

red border is geometry Area and black border is text area

当前使用Xcode12 Beta 3

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

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

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)
    }
}

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

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

1-父母提供其尺寸

2个孩子选择其大小

3父母将其孩子定位

但是我认为这是不对的!

text is taking the whole geometry space

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

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

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)
    }
}

这给出了以下内容:

Xcode preview

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

我们将顺序切换为此,这样背景视图仅适用于“文本”视图,我们可以看到“文本”视图的大小:

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)
    }
}

这提供了我认为您希望在“文本”视图中获得的结果仅占用所需的最小大小,并遵循了@twostraws很好解释的那些规则。

Xcode preview as expected

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