1.5 为视图添加背景

原文链接: https://developer.apple.com/documentation/swiftui/adding-a-background-to-your-view

1.5 为视图添加背景

在视图后面组合出一个背景,并把它延伸到安全区域内边距之外。

概述

你可以用 background(alignment:content:) 视图修饰符把一个视图添加为背景。要在多个视图下添加背景,或者让背景比现有视图更大,你可以把这些视图放进一个 ZStack 中来分层,并把你想作为背景的视图放在视图栈的最底层。你还可以指定背景视图忽略安全区域内边距,从而把背景延伸到部分或全部边缘。

添加背景

如果你的设计需要背景,可以用 background(alignment:content:) 修饰符在现有视图下方添加一个背景。下面的示例用 background(alignment:content:) 视图修饰符为垂直栈添加了一个渐变:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
let backgroundGradient = LinearGradient(
    colors: [Color.red, Color.blue],
    startPoint: .top, endPoint: .bottom)

struct SignInView: View {
    @State private var name: String = ""

    var body: some View {
        VStack {
            Text("Welcome")
                .font(.title)
            HStack {
                TextField("Your name?", text: $name)
                    .textFieldStyle(.roundedBorder)
                Button(action: {}, label: {
                    Image(systemName: "arrow.right.square")
                        .font(.title)
                })
            }
            .padding()
        }
        .background {
            backgroundGradient
        }
    }
}

background(alignment:content:) 视图修饰符会把背景视图的尺寸约束为与它附着的视图相同:

一张 iPhone 截图,显示欢迎标题、文本输入框以及水平栈中的按钮具有渐变背景,但手机背景的其余部分没有填充。

把背景扩展到视图下方

要创建一个比垂直栈更大的背景,需要使用另一种技巧。你可以在 VStack 中内容的上下方添加 Spacer 视图来扩展它,但这样也会扩大栈的尺寸,可能改变其布局。要在不改变栈尺寸的情况下加入更大的背景,请把这些视图嵌套进一个 ZStack,把 VStack 层叠在背景视图之上:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
struct SignInView: View {
    @State private var name: String = ""

    var body: some View {
        ZStack {
            backgroundGradient
            VStack {
                Text("Welcome")
                    .font(.title)
                HStack {
                    TextField("Your name?", text: $name)
                        .textFieldStyle(.roundedBorder)
                    Button(action: {}, label: {
                        Image(systemName: "arrow.right.square")
                            .font(.title)
                    })
                }
                .padding()
            }
        }
    }
}

与使用 background 视图修饰符时不同,深度栈中各视图的尺寸彼此独立。Gradient 中的视图会扩展以填满栈可用的空间,但默认会避开安全区域内边距:

一张 iPhone 截图,显示渐变背景几乎填满整个背景,但不包括顶部状态栏和底部栏。

关于使用栈来组合视图的更多信息,请参阅 用栈视图构建布局。

把背景延伸进安全区域

默认情况下,SwiftUI 会调整视图的尺寸和位置以避开系统定义的安全区域,从而确保系统内容或设备边缘不会遮挡你的视图。如果你的设计要求背景延伸到屏幕边缘,请使用 ignoresSafeArea(_:edges:) 修饰符覆盖默认行为。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
struct SignInView: View {
    @State private var name: String = ""
    var body: some View {
        ZStack {
            backgroundGradient
            VStack {
                Text("Welcome")
                    .font(.title)
                HStack {
                    TextField("Your name?", text: $name)
                        .textFieldStyle(.roundedBorder)
                    Button(action: {}, label: {
                        Image(systemName: "arrow.right.square")
                            .font(.title)
                    })
                }
                .padding()
            }
        }
        .ignoresSafeArea()
    }
}

背景渐变会填满设备的显示区域,并忽略安全区域内边距。

一张 iPhone 截图,显示渐变背景填满整个背景。

显示键盘时调整视图

你可以通过添加 ignoresSafeArea(_:edges:) 修饰符来忽略键盘的安全区域。当你激活键盘时,垂直栈中的内容保持不动,忽略键盘占用的空间:

一张 iPhone 截图,显示渐变背景填满整个背景,键盘叠加在屏幕底部。水平栈中的欢迎标题、文本输入框和按钮居中于 iPhone 的顶部和底部之间,键盘遮挡了背景的下半部分。

要让垂直栈的内容遵守安全区域并随键盘调整,请把该修饰符移到只作用于背景视图上。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
struct SignInView: View {
    @State private var name: String = ""
    var body: some View {
        ZStack {
            backgroundGradient
                .ignoresSafeArea()
            VStack {
                Text("Welcome")
                    .font(.title)
                HStack {
                    TextField("Your name?", text: $name)
                        .textFieldStyle(.roundedBorder)
                    Button(action: {}, label: {
                        Image(systemName: "arrow.right.square")
                            .font(.title)
                    })
                }
                .padding()
            }
        }
    }
}

为了适应键盘,SwiftUI 会调整你的视图尺寸和位置。由于背景视图带有 ignoresSafeArea(_:edges:) 修饰符,它保持不变。

一张 iPhone 截图,显示渐变背景填满整个背景,键盘叠加在屏幕底部。水平栈中的欢迎标题、文本输入框和按钮居中于键盘顶部和 iPhone 顶部之间,渐变背景在键盘下方延伸到 iPhone 的整个高度。