我是新手 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)
}
}