我要实现的目标
我正在尝试创建一个 SwiftUI View ,其中图像应扩展整个屏幕 (edgesIgnoringSafeArea(.all)
),然后在其上覆盖一个 View ,该 View 也填充整个屏幕屏幕,但尊重安全区域。
我尝试过的
这是我的代码,接近:
struct Overlay: View {
var body: some View {
VStack {
HStack {
EmptyView()
Spacer()
Text("My top/right aligned view.")
.padding()
.background(Color.red)
}
Spacer()
HStack {
Text("My bottom view")
.padding()
.background(Color.pink)
}
}
}
}
struct Overlay_Previews: PreviewProvider {
static var previews: some View {
ZStack {
Image(uiImage: UIImage(named: "background")!)
.resizable()
.edgesIgnoringSafeArea(.all)
.aspectRatio(contentMode: .fill)
Overlay()
}
}
}
问题和经过测试的解决方案
问题是图像没有被剪裁成它看起来的样子,所以它将父 View 扩展到大于屏幕宽度的宽度,然后使右上角对齐的红色文本框漂浮在屏幕外(见图)。
我尝试在不同的地方使用 .clipped()
,但没有成功。如果可能,我最好避免使用 GeometryReader
。
问:如何让 ImageView 只填满屏幕?
最佳答案
在被 ZStack 拾取之前,您必须限制越界 Image 的帧大小以避免 ZStack 增长,因此 Overlay 会偏离位置。
编辑:aheze 通过将 Image
放入 Overlay() 的背景中,在他的回答中展示了一种使用
与 GeometryReader
的方法.background(Image()..)
。这完全避免了 ZStack
和 GeometryReader
的使用,并且可能是一个更简洁的解决方案。
基于父 View 大小
struct IgnoringEdgeInsetsView2: View {
var body: some View {
ZStack {
GeometryReader { geometry in
Image("smile")
.resizable()
.aspectRatio(contentMode: .fill)
.edgesIgnoringSafeArea(.all)
.frame(maxWidth: geometry.size.width,
maxHeight: geometry.size.height)
}
Overlay()
}
}
}
基于屏幕尺寸
struct IgnoringEdgeInsetsView: View {
var body: some View {
ZStack {
Image("smile-photo")
.resizable()
.aspectRatio(contentMode: .fill)
.edgesIgnoringSafeArea(.all)
.frame(maxWidth: UIScreen.main.bounds.width,
maxHeight: UIScreen.main.bounds.height)
Overlay()
}
}
}
关于SwiftUI:防止 Image() 将 View 矩形扩展到屏幕边界之外,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57593552/