【发布时间】:2019-11-29 10:18:33
【问题描述】:
我是 SwiftUI 的新手。我想设计一个带有少量控件和背景图像的自定义视图。背景图像应覆盖整个视图。它应该看起来像屏幕的水印。如何使用 SwiftUI 实现这一目标?
【问题讨论】:
标签: ios swift xcode mobile swiftui
我是 SwiftUI 的新手。我想设计一个带有少量控件和背景图像的自定义视图。背景图像应覆盖整个视图。它应该看起来像屏幕的水印。如何使用 SwiftUI 实现这一目标?
【问题讨论】:
标签: ios swift xcode mobile 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
}
}
}
}
【讨论】:
如果您只想使用全屏宽度和高度,并且不关心图像的纵横比,您可以使用 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)
【讨论】: