我使用GeometryReader()和.frame()来显示它们的可比性,并使用它们的宽度。但是,当宽度小于最小时,用GeometryReader()包装的对象没有中心对齐。有关演示,请参阅附件中的gifs。
你能帮我整理一下吗?
理想:

当前:

struct ExampleView: View {
@State private var width: CGFloat = 50
var body: some View {
VStack {
SubView()
.frame(width: self.width, height: 120)
.border(Color.blue, width: 2)
Text("Offered Width is \(Int(width))")
Slider(value: $width, in: 0...200, step: 5)
}
}
}
struct SubView: View {
var body: some View {
GeometryReader { geometry in
Rectangle()
.fill(Color.yellow.opacity(0.6))
.frame(width: max(geometry.size.width, 120), height: max(geometry.size.height, 120))
}
}
}发布于 2022-05-16 10:43:33
那是因为GeometryReader没有把它的孩子集中在中心。
您必须通过添加一个Rectangle修饰符或一个.offset来手动定位.position。
.position将相对于父中心移动矩形帧的原点。
.offset不会改变框架,而是改变呈现(就像翻译的CGAffineTransform一样)。
Rectangle的下列修饰符将在视觉上产生相同的结果(尽管在遮罩下不同):
Rectangle()
.fill(Color.yellow.opacity(0.6))
.frame(width: max(geometry.size.width, 120), height: max(geometry.size.height, 120))
.position(x: geometry.size.width / 2, y: geometry.size.height / 2)或
let rectWidth = max(geometry.size.width, 120)
Rectangle()
.fill(Color.yellow.opacity(0.6))
.frame(width: rectWidth, height: max(geometry.size.height, 120))
.offset(x: ((geometry.size.width - rectWidth) / 2), y: 0)请注意,矩形的框架超出了其父框的边界。我建议避免这样做,因为它会导致在屏幕上放置其他UI元素的各种困难。
您可以反过来构建它(除非您的实际目标是了解GeometryReader的工作原理):
struct ExampleView: View {
@State private var width: CGFloat = 50
var body: some View {
VStack {
let minWidth: CGFloat = 120
let subViewWidth: CGFloat = max(minWidth, width)
SubView(desiredWidth: width)
.frame(width: subViewWidth, height: 120)
.background(.yellow.opacity(0.6))
Text("Offered Width is \(Int(width))")
Slider(value: $width, in: 0...200, step: 5)
}
}
}
struct SubView: View {
let desiredWidth: CGFloat
var body: some View {
Rectangle()
.fill(.clear)
.border(Color.blue, width: 2)
.frame(width: desiredWidth, height: nil)
}
}在这个例子中,SubView有一个黄色的填充和一个最小的框架宽度,而内部的矩形只是接受在滑块上设置的任何宽度。它也不再需要GeometryReader了。它的外观和行为都是一样的,但是没有一个视图超过其父视图的界限。
https://stackoverflow.com/questions/72250734
复制相似问题