SwiftUI 的 ContentUnavailableView
是 Apple 在 iOS 17 及更新版本中提供的新组件,旨在帮助开发者更简单、更直观地向用户展示 “内容不可用” 的状态页面。这种状态通常会用在数据为空或发生错误时的场景,比如空白列表、网络断开时的消息等。
1. ContentUnavailableView
的核心作用
#
ContentUnavailableView
提供了一种清晰且一致的方式,用于在应用中表现 “当前未有可显示内容” 的状态。其核心功能是:
- 展示一段简洁的文字说明,让用户知道系统或页面当前的状态。
- 提供一致的用户体验,与原生 Apple 应用相匹配(如 iOS 的“邮件”和“照片”应用中的空状态页面)。
- 支持图标、标题、描述和操作按钮等配件内容,提供更灵活的设计。
- 自动适配平台的 UI 样式(如 iOS、macOS 或 watchOS)。
2. 为什么需要 ContentUnavailableView
?
#
在苹果提供 ContentUnavailableView
之前,开发者通常需要自行构建空状态页面,例如用 VStack
自定义布局。这种方法虽然灵活,但在以下方面存在一些不足:
- 不一致的用户体验:不同开发者实现的空状态页面可能缺乏规范性,使得整体体验与系统风格不统一。
- 不灵活的设计:开发者需要手动处理布局、图标、文字间距等细节。
- 难以适配不同屏幕尺寸或平台:例如,适配 iPhone 与 iPad 可能需要额外处理。
ContentUnavailableView
的引入解决了上述问题,提供了一个开箱即用的组件,帮助开发者快速实现一致、美观的空状态页面。
3. 什么时候使用 ContentUnavailableView
?
#
你可以在以下场景中使用 ContentUnavailableView
:
3.1 数据为空的场景 #
当用户进入页面,但没有足够的数据展示内容时:
- 示例:一个用户打开“收藏夹”页面,但没有收藏任何内容。
- 系统行为:显示一个明确的提示,例如“没有任何收藏内容”。
import SwiftUI
struct EmptyFavoritesView: View {
var body: some View {
ContentUnavailableView("没有收藏内容", systemImage: "star.slash")
}
}
3.2 网络错误或客户端错误 #
如果页面中的数据加载失败(如网络断开或服务端错误),你可以使用 ContentUnavailableView
来提醒用户,并引导其采取行动。
import SwiftUI
struct NetworkErrorView: View {
var body: some View {
ContentUnavailableView("网络连接失败",
systemImage: "wifi.exclamationmark",
description: Text("请检查你的网络设置并重试。"))
}
}
- 图标(
systemImage
)直观地提醒用户问题类型。 - 提供文字描述,解释错误原因。
3.3 搜索结果为空 #
当用户在输入搜索关键词时,结果为空,ContentUnavailableView
可用于提示“找不到内容”。
import SwiftUI
struct EmptySearchView: View {
var body: some View {
ContentUnavailableView("未找到结果",
systemImage: "magnifyingglass.circle",
description: Text("尝试更改关键字并重新搜索。"))
}
}
3.4 功能受限或未授权 #
在某些特定功能需要用户权限时(比如定位、存储权限),可以使用 ContentUnavailableView
提示功能限制,并指引用户授权。
import SwiftUI
struct PermissionRequiredView: View {
var body: some View {
ContentUnavailableView("无法访问位置",
systemImage: "location.slash",
description: Text("请启用定位服务以使用此功能。"))
}
}
3.5 用户操作成功后,暂无进一步操作 #
当某个任务完成且没有其他可操作的事项时,可以提示用户当前没有其他内容。
4. 如何使用 ContentUnavailableView
?
#
ContentUnavailableView
有多个方便的初始化方法,可以根据具体需求快速设置内容。
4.1 最简化用法 #
你可以只传递一个标题。
ContentUnavailableView("暂无内容")
4.2 添加系统图标 #
通过 systemImage
参数为状态添加直观的图标:
ContentUnavailableView("暂无收藏", systemImage: "star.slash")
4.3 添加描述说明 #
可以为状态补充更详细的说明:
ContentUnavailableView("找不到内容", systemImage: "magnifyingglass.circle", description: Text("请尝试输入其他搜索条件。"))
4.4 添加自定义操作按钮 #
可以为当前状态添加操作按钮,让用户可以采取补救措施。
import SwiftUI
struct RetryView: View {
var body: some View {
ContentUnavailableView("网络连接失败",
systemImage: "wifi.exclamationmark",
description: Text("检查您的网络连接后,点击重试。")) {
Button("重试") {
print("Retry tapped!")
}
}
}
}
5. 可用的自定义项 #
- 标题:
String
:主标题,展示状态的核心信息。 - 图标:
systemImage
名称:用于暗示状态的直观符号(系统 SF Symbols 图标)。 - 描述:
Text
:详细说明当前状态的原因或建议。 - 按钮:
ViewBuilder
:通过添加按钮提供额外的操作选项。
6. 与自定义空状态页面的对比 #
ContentUnavailableView
的优点:
#
- 一致性:
- 提供与系统风格一致的布局和图标,用户体验更统一。
- 适配性:
- 自动支持不同屏幕尺寸、系统主题(浅色/深色)以及平台特性。
- 可复用性:
- 大量空状态场景可以通过快速配置
ContentUnavailableView
复用。
- 大量空状态场景可以通过快速配置
7. Apple 的应用案例 #
ContentUnavailableView
体现了 Apple 在系统应用中的设计实践。例如:
- iOS 的“照片”应用:
- 没有照片时,会显示“没有照片”以及相关图标提示。
- iOS 的“文件”应用:
- 空文件夹时,显示“没有文件”的提示。
8. 实际案例:与 NavigationStack
和 ScrollView
结合
#
ContentUnavailableView
可以与 SwiftUI 的其他组件轻松结合。例如,当列表数据为空,你可以动态切换到空状态视图。
struct ContentView: View {
@State private var items: [String] = []
var body: some View {
NavigationStack {
if items.isEmpty {
ContentUnavailableView("没有可显示的内容", systemImage: "tray")
} else {
List(items, id: \.self) { item in
Text(item)
}
}
.navigationTitle("我的列表")
}
}
}
总结 #
ContentUnavailableView
是 SwiftUI 用于处理空状态场景的强大工具,它有以下特点:
- 简洁优雅的 API: 通过简单的几行代码快速创建状态页面。
- 一致的用户体验: 自动适配平台风格,无需担心跨平台差异。
- 高度灵活: 支持标题、图标、描述和操作按钮多种内容组合。
使用建议: #
当页面内容为空、加载失败或操作受限时,可以优先使用 ContentUnavailableView
。它不仅使开发更高效,还确保了用户界面设计的专业性和一致性。