我是 SwiftUI 的新手。我想设计一个包含少量控件和背景图像的自定义视图。背景图像应覆盖整个视图。它应该看起来像屏幕的水印。如何使用 SwiftUI 实现此目的?
使用ZStack
但不使用UIScreen
:
var body: some View {
ZStack {
Image("BG")
.resizable()
.scaledToFill()
.edgesIgnoringSafeArea(.all)
Text("Hello world")
}
}
如果您支持多屏幕应用、可调整大小的窗口、多窗口应用等,则使用UIScreen
将导致你的应用出现不希望的行为。
试试这个:
var body: some View {
ZStack {
Text("Hello")
}
.background(
Image("Background")
.resizable()
.edgesIgnoringSafeArea(.all)
.frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
)
}
更新
与 iOS 15 Xcode 13.2
public extension View {
func fullBackground(imageName: String) -> some View {
return background(
Image(imageName)
.resizable()
.scaledToFill()
.edgesIgnoringSafeArea(.all)
)
}
}
用
YourView
.fullBackground(imageName: "imageName")
结束更新
旧答案
我更喜欢@ViewBuilder
用法:
BackgroundView(imageName: "image name") {
Text("Hello")
}
@ViewBuilder
public struct BackgroundView <Content : View> : View {
public var content : Content
public var imageName: String
public var opacity: Double
public init(imageName: String, opacity: Double=1,@ViewBuilder content: () -> Content) {
self.content = content()
self.imageName = imageName
self.opacity = opacity
}
public var body: some View {
GeometryReader { geo in
ZStack {
Image(imageName)
.resizable()
.scaledToFill()
.edgesIgnoringSafeArea(.all)
.frame(width: geo.size.width, height: geo.size.height, alignment: .center)
.opacity(opacity)
content
}
}
}
}
Mojtaba 的答案是不完整的。问题是图像的边界框可能会超过屏幕,从而导致不希望的行为。为了纠正这一点,我们需要在组合中添加.frame
。这将确保图像与屏幕一样大并解决我们的问题。
struct BackgroundView: View {
var body: some View {
GeometryReader { proxy in
Image("Background")
.resizable()
.scaledToFill()
.frame(width: proxy.size.width, height: proxy.size.height)
.clipped()
}.ignoresSafeArea()
}
}
如果您只想使用全屏宽度和高度,并且不关心图像的纵横比,则可以使用 UIScreen 大小的几何阅读器。
.frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
此行代码会将映像设置为设备的最大大小。根据您的父视图和设备,您可能需要使用:
.edgesIgnoringSafeArea(.all)
这将忽略iPhone X及更高设备上的安全区域。
您可以使用如下所示ZStack
来实现此目的。您可以对Image
添加更多控制,例如我添加了Text()
var body: some View {
ZStack{
Image("your image")
.frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
Text("Hello World").foregroundColor(.white).font(.system(size: 20)).bold()
}
}
您可以使用忽略SafeArea
.edgesIgnoringSafeArea(.all)
struct LoginView: View {
var body: some View {
Image("imageName")
.resizable()
.ignoresSafeArea(.all)
}
}