前言
SwiftUI 引入了新的 ContentUnavailableView
类型,允许我们在应用程序中展示空状态、错误状态或任何其他内容不可用的状态。本周,我们将学习如何使用 ContentUnavailableView
引导用户浏览应用程序中的空状态。
基本用法
让我们从展示 ContentUnavailableView
视图的基本用法开始。
swift
struct ContentView: View {
let store: Store
var body: some View {
NavigationStack {
List(store.products, id: \.self) { product in
Text(verbatim: product)
}
.navigationTitle("Products")
.overlay {
if store.products.isEmpty {
ContentUnavailableView(
"Connection issue",
systemImage: "circle"
)
}
}
}
}
}
在上面的示例中,我们将 ContentUnavailableView
定义为产品列表的叠加层。每当产品列表为空时,我们使用带有标题和图像的 ContentUnavailableView
显示。ContentUnavailableView
的另一种变体还允许我们定义当前状态的描述文本。
自定义视图
swift
struct ContentView: View {
let store: Store
var body: some View {
NavigationStack {
List(store.products, id: \.self) { product in
Text(verbatim: product)
}
.navigationTitle("Products")
.overlay {
if store.products.isEmpty {
ContentUnavailableView {
Label("Connection issue", systemImage: "wifi.slash")
} description: {
Text("Check your internet connection")
} actions: {
Button("Refresh") {
store.fetch()
}
}
}
}
}
}
}
ContentUnavailableView
还允许我们在描述文本下方显示操作按钮。因此,ContentUnavailableView
初始化程序的另一种变体允许我们使用 ViewBuilder
闭包定义视图的每个部分,从而完全自定义其外观和感觉。
搜索屏幕使用
swift
struct ContentView: View {
@Bindable var store: Store
var body: some View {
NavigationStack {
List(store.products, id: \.self) { product in
Text(verbatim: product)
}
.navigationTitle("Products")
.overlay {
if store.products.isEmpty {
ContentUnavailableView.search
}
}
.searchable(text: $store.query)
}
}
}
在搜索屏幕显示搜索结果时,可以使用 ContentUnavailableView
类型的搜索功能。它由框架本地化,并遍历视图层次结构以找到搜索栏并提取其文本以显示在视图内。
手动提供查询
swift
struct ContentView: View {
@Bindable var store: Store
var body: some View {
NavigationStack {
List(store.products, id: \.self) { product in
Text(verbatim: product)
}
.navigationTitle("Products")
.overlay {
if store.products.isEmpty {
ContentUnavailableView.search(text: store.query)
}
}
.searchable(text: $store.query)
}
}
}
你还可以通过使用 ContentUnavailableView
类型的搜索功能并提供单个参数来手动将查询输入描述中。
可运行 Demo
完整可以运行的 Demo 需要有相关的环境和依赖项,而代码片段中涉及到了一些 Store
和其他可能的模型或服务。由于代码片段中的 Store
类型未提供,我将使用一个简化版本的示例代码来创建一个简单的 SwiftUI Demo,以展示 ContentUnavailableView
的基本使用。
swift
import SwiftUI
struct Product: Identifiable {
let id: UUID
let name: String
}
class ProductStore: ObservableObject {
@Published var products: [Product] = []
func fetchProducts() {
// Simulating product fetching
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
self.products = [Product(id: UUID(), name: "iPhone"), Product(id: UUID(), name: "iPad")]
}
}
}
struct ContentView: View {
@StateObject var store = ProductStore()
var body: some View {
NavigationView {
List(store.products) { product in
Text(product.name)
}
.navigationTitle("Products")
.overlay {
if store.products.isEmpty {
ContentUnavailableView(
"No Products",
systemImage: "exclamationmark.triangle"
)
}
}
.onAppear {
store.fetchProducts()
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
上述代码中,我们创建了一个简单的 Product
结构体表示产品,以及一个 ProductStore
类作为存储产品的模拟服务。在 ContentView
中,我们使用 ContentUnavailableView
来处理产品为空的情况。
请确保在 Xcode 中创建一个新的 SwiftUI 项目,并将上述代码替换到主 ContentView 中,然后运行该项目。在项目的初始加载时,ContentUnavailableView
将显示"No Products"消息,几秒后模拟产品加载,之后产品列表将显示在主视图中。
总结
今天,我们学习了如何在 SwiftUI 中使用 ContentUnavailableView
类型以用户友好的方式显示空状态。通过这些简单而强大的功能,我们能够更好地引导用户,使他们能够理解应用程序的当前状态。 ContentUnavailableView
的灵活性和易用性为我们处理应用程序中的不可用状态提供了有力的工具。