GeometryReader 大小计算 SwiftUI
GeometryReader Size Calculations SwiftUI
我正在尝试使用 GeometryReader 放置视图。我用 GeometryReader 来
修改一个 Rectangle() 并按照我的预期放置它。但是,我想以编程方式
将 y 值设置为与 VStack 框架的顶部对齐。我以为我可以读书
文本字段的几何高度并使用它,但我无法分配几何
textField 的维度到一个变量,即使我使用相同的概念来移动
矩形。
如图:
简单代码:
struct ContentView: View {
@State private var textHeight = 0.0
var body: some View {
VStack {
GeometryReader { geometry in
VStack {
Text("Title Text")
}
//self.textHeight = CGFloat(geometry.size.height)
}.border(Color.green)
GeometryReader { geometry in
Rectangle()
.path(in: CGRect(x: geometry.size.width - 50,
y: 0, width: geometry.size.width / 2.0,
height: geometry.size.height / 2))
.fill(Color.red)
}
}.frame(width: 150, height: 300).border(Color.black)
}
}
Xcode 测试版 7,卡特琳娜测试版 7
任何指导将不胜感激。
问题是您使用的 VStack
里面有两个 GeometryReader
。 VStack
将其子项垂直放置,一个在另一个之上。你的第二个 GeometryReader
的 y=0
是第一个 在 第一个 GeometryReader
之后。我建议你改变你设计 UI 的方式,例如你可以通过这种方式获得相同的结果:
struct ContentView: View {
var body: some View {
GeometryReader { geometry in
VStack {
ZStack {
Rectangle()
.path(in: CGRect(x: geometry.size.width - 50, y: 0, width: geometry.size.width / 2.0, height: geometry.size.height / 4))
.fill(Color.red)
Text("Title Text")
.frame(width: geometry.size.width, height: geometry.size.height/2.0)
.border(Color.green)
}
Spacer()
}
}
.frame(width: 150, height: 300).border(Color.black)
}
}
结果是:
要将内容上下推送或推送到 left/right,您可以使用非常有用的 Spacer
视图。
这是我的建议,但是如果你真的需要使用两个GeometryReader
你必须这样做:
struct ContentView2: View {
@State private var textHeight = CGFloat(0)
private func firstContentView(geometry: GeometryProxy) -> some View {
textHeight = geometry.size.height
return Text("Title Text")
.position(x: geometry.size.width/2.0, y: geometry.size.height/2.0)
}
var body: some View {
VStack(spacing: 0) {
GeometryReader { geometry in
self.firstContentView(geometry: geometry)
}.border(Color.green)
GeometryReader { geometry in
Rectangle()
.path(in: CGRect(x: geometry.size.width - 50, y: -self.textHeight, width: geometry.size.width / 2.0, height: geometry.size.height / 2))
.fill(Color.red)
}
}.frame(width: 150, height: 300).border(Color.black)
}
}
但这是一个非常肮脏的解决方案。
我正在尝试使用 GeometryReader 放置视图。我用 GeometryReader 来 修改一个 Rectangle() 并按照我的预期放置它。但是,我想以编程方式 将 y 值设置为与 VStack 框架的顶部对齐。我以为我可以读书 文本字段的几何高度并使用它,但我无法分配几何 textField 的维度到一个变量,即使我使用相同的概念来移动 矩形。
如图:
struct ContentView: View {
@State private var textHeight = 0.0
var body: some View {
VStack {
GeometryReader { geometry in
VStack {
Text("Title Text")
}
//self.textHeight = CGFloat(geometry.size.height)
}.border(Color.green)
GeometryReader { geometry in
Rectangle()
.path(in: CGRect(x: geometry.size.width - 50,
y: 0, width: geometry.size.width / 2.0,
height: geometry.size.height / 2))
.fill(Color.red)
}
}.frame(width: 150, height: 300).border(Color.black)
}
}
Xcode 测试版 7,卡特琳娜测试版 7 任何指导将不胜感激。
问题是您使用的 VStack
里面有两个 GeometryReader
。 VStack
将其子项垂直放置,一个在另一个之上。你的第二个 GeometryReader
的 y=0
是第一个 在 第一个 GeometryReader
之后。我建议你改变你设计 UI 的方式,例如你可以通过这种方式获得相同的结果:
struct ContentView: View {
var body: some View {
GeometryReader { geometry in
VStack {
ZStack {
Rectangle()
.path(in: CGRect(x: geometry.size.width - 50, y: 0, width: geometry.size.width / 2.0, height: geometry.size.height / 4))
.fill(Color.red)
Text("Title Text")
.frame(width: geometry.size.width, height: geometry.size.height/2.0)
.border(Color.green)
}
Spacer()
}
}
.frame(width: 150, height: 300).border(Color.black)
}
}
结果是:
要将内容上下推送或推送到 left/right,您可以使用非常有用的 Spacer
视图。
这是我的建议,但是如果你真的需要使用两个GeometryReader
你必须这样做:
struct ContentView2: View {
@State private var textHeight = CGFloat(0)
private func firstContentView(geometry: GeometryProxy) -> some View {
textHeight = geometry.size.height
return Text("Title Text")
.position(x: geometry.size.width/2.0, y: geometry.size.height/2.0)
}
var body: some View {
VStack(spacing: 0) {
GeometryReader { geometry in
self.firstContentView(geometry: geometry)
}.border(Color.green)
GeometryReader { geometry in
Rectangle()
.path(in: CGRect(x: geometry.size.width - 50, y: -self.textHeight, width: geometry.size.width / 2.0, height: geometry.size.height / 2))
.fill(Color.red)
}
}.frame(width: 150, height: 300).border(Color.black)
}
}
但这是一个非常肮脏的解决方案。