I am new to SwiftUI. I want to design a custom view with few controls and a background image. The background image should cover the complete view. It should look like a watermark for the screen. How can I achieve this using SwiftUI?
Use ZStack
but Don't use UIScreen
:
var body: some View {
ZStack {
Image("BG")
.resizable()
.scaledToFill()
.edgesIgnoringSafeArea(.all)
Text("Hello world")
}
}
Using UIScreen
will lead your app to undesired behavior if you are supporting multiscreen app, resizable windows, multiwindow app, etc.
Try this:
var body: some View {
ZStack {
Text("Hello")
}
.background(
Image("Background")
.resizable()
.edgesIgnoringSafeArea(.all)
.frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
)
}
If you just want to use the full screen width and height, and you don't bother about the aspect ratio of the image, you can either use a geometry reader of the UIScreen size's.
.frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
This line of code will set the Image to the max size of the device. Depending on your parent view and device, you may need to use:
.edgesIgnoringSafeArea(.all)
This will ignore the safe area's on iPhone X devices and above.
You can achieve this using ZStack
like below. You can add more control on Image
for example I added 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()
}
}
You can Ignore SafeArea
using
.edgesIgnoringSafeArea(.all)
I prefer a @ViewBuilder
Usage:
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
}
}
}
}
The answer of Mojtaba is incomplete. The problem is the bounding box of the image can exceed the screen leading to undesired behavior. To correct this we need to add .frame
to the mix. This will make sure the image is as large as the screen and fixes our problem.
var body: some View {
ZStack {
Image("Background")
.resizable()
.scaledToFill()
.frame(minWidth: 0, maxHeight: .infinity)
.edgesIgnoringSafeArea(.all)
Text("Hello world")
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.