SwiftUI — ContentUnavailableView

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 的优点: #

  1. 一致性:
    • 提供与系统风格一致的布局和图标,用户体验更统一。
  2. 适配性:
    • 自动支持不同屏幕尺寸、系统主题(浅色/深色)以及平台特性。
  3. 可复用性:
    • 大量空状态场景可以通过快速配置 ContentUnavailableView 复用。

7. Apple 的应用案例 #

ContentUnavailableView 体现了 Apple 在系统应用中的设计实践。例如:

  • iOS 的“照片”应用:
    • 没有照片时,会显示“没有照片”以及相关图标提示。
  • iOS 的“文件”应用:
    • 空文件夹时,显示“没有文件”的提示。

8. 实际案例:与 NavigationStackScrollView 结合 #

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 用于处理空状态场景的强大工具,它有以下特点:

  1. 简洁优雅的 API: 通过简单的几行代码快速创建状态页面。
  2. 一致的用户体验: 自动适配平台风格,无需担心跨平台差异。
  3. 高度灵活: 支持标题、图标、描述和操作按钮多种内容组合。

使用建议: #

当页面内容为空、加载失败或操作受限时,可以优先使用 ContentUnavailableView。它不仅使开发更高效,还确保了用户界面设计的专业性和一致性。

本文共 2361 字,上次修改于 Jan 18, 2025