SwiftUI:根据顶层在ZStack中安排中间层
SwiftUI: Arrange middle layer in ZStack dependent on top layer
我想实现一个UI,其中有
- 背景图片,全屏并随设备尺寸缩放
- 在背景图像上方和主图像下方的渐变 UI,底部对齐,其大小取决于主图像中一个元素的位置 UI
- 主要 UI 具有多个界面元素的 VStack。有一个顶部区域和一个底部区域,它们都是固定对齐和大小的,中间有一个可变的间隔
此模型显示了 3 层 ZStack 的预期排列(从左到右):
这是我在 Swift 中得到的UI:
struct TestView: View {
var body: some View {
ZStack() {
// BG Image
Image("BgImg")
.resizable()
.scaledToFill()
.frame(width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.width)
// Gradient
VStack {
Spacer()
Rectangle()
.fill(
LinearGradient(gradient: Gradient(stops: [
Gradient.Stop(color: Color(.black).opacity(0.0), location: 0),
Gradient.Stop(color: Color(.black), location: 0.5),
]), startPoint: .top, endPoint: .bottom)
)
// HOW TO GET THE RIGHT SIZE HERE?
.frame(height:500)
}
// Main UI
VStack {
// VStack 1
VStack {
Text("ABC")
Text("DEF")
}.frame(height:260)
// Fixed spacer
Spacer().frame(height:26)
// VStack 2
VStack {
Text("123").foregroundColor(.white)
Text("456").foregroundColor(.white)
}.frame(height:162)
// Variable spacer
Spacer()
// VStack 2
VStack {
Text("!!!").foregroundColor(.white)
Text("???").foregroundColor(.white)
}.frame(height:304)
}
// Fixed spacer top
.padding(.top, 26)
// Fixed spacer bottom
.padding(.bottom, 32)
}
.edgesIgnoringSafeArea(.all)
}
}
struct TestView_Previews: PreviewProvider {
static var previews: some View {
TestView()
.previewDevice("iPhone 13 Pro")
.preferredColorScheme(.light)
}
}
我的问题是:
- 如何正确调整渐变大小?
- 为什么渐变现在对齐到底部,为什么背景图像不能缩放到全屏,请参见预览屏幕截图的底部
对于非全屏的图片,需要让图片忽略安全区域,而不仅仅是ZStack;
您需要使用几何体 reader 读取直到堆栈末尾的高度,然后将其分配给用于调整渐变大小的值。
我想实现一个UI,其中有
- 背景图片,全屏并随设备尺寸缩放
- 在背景图像上方和主图像下方的渐变 UI,底部对齐,其大小取决于主图像中一个元素的位置 UI
- 主要 UI 具有多个界面元素的 VStack。有一个顶部区域和一个底部区域,它们都是固定对齐和大小的,中间有一个可变的间隔
此模型显示了 3 层 ZStack 的预期排列(从左到右):
这是我在 Swift 中得到的UI:
struct TestView: View {
var body: some View {
ZStack() {
// BG Image
Image("BgImg")
.resizable()
.scaledToFill()
.frame(width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.width)
// Gradient
VStack {
Spacer()
Rectangle()
.fill(
LinearGradient(gradient: Gradient(stops: [
Gradient.Stop(color: Color(.black).opacity(0.0), location: 0),
Gradient.Stop(color: Color(.black), location: 0.5),
]), startPoint: .top, endPoint: .bottom)
)
// HOW TO GET THE RIGHT SIZE HERE?
.frame(height:500)
}
// Main UI
VStack {
// VStack 1
VStack {
Text("ABC")
Text("DEF")
}.frame(height:260)
// Fixed spacer
Spacer().frame(height:26)
// VStack 2
VStack {
Text("123").foregroundColor(.white)
Text("456").foregroundColor(.white)
}.frame(height:162)
// Variable spacer
Spacer()
// VStack 2
VStack {
Text("!!!").foregroundColor(.white)
Text("???").foregroundColor(.white)
}.frame(height:304)
}
// Fixed spacer top
.padding(.top, 26)
// Fixed spacer bottom
.padding(.bottom, 32)
}
.edgesIgnoringSafeArea(.all)
}
}
struct TestView_Previews: PreviewProvider {
static var previews: some View {
TestView()
.previewDevice("iPhone 13 Pro")
.preferredColorScheme(.light)
}
}
我的问题是:
- 如何正确调整渐变大小?
- 为什么渐变现在对齐到底部,为什么背景图像不能缩放到全屏,请参见预览屏幕截图的底部
对于非全屏的图片,需要让图片忽略安全区域,而不仅仅是ZStack;
您需要使用几何体 reader 读取直到堆栈末尾的高度,然后将其分配给用于调整渐变大小的值。