大多数浏览器和
Developer App 均支持流媒体播放。
-
最新单元格配置方法
学习网格视图与列表视图单元格的最新配置技巧,在你所开发的 app 中更为快速地构造动态界面。探索不同的配置类型及其使用方法,以便轻易地为单元格填充内容或应用常用样式。学习如何利用功能强大的 API 为单元格的不同状态进行外观自定义。了解设计模式与其应用方面的最佳实践,以便简化代码、消除错误与提升性能。
资源
相关视频
WWDC22
WWDC21
WWDC20
-
下载
(你好 WWDC 2020)
大家好 欢迎来到 WWDC
欢迎来到《现代单元格配置》 我是 Tyler Fox UIKit 团队的一名工程师 在 iOS 14 中 我们通过构建基础技术 为 UICollectionView 带来全新的功能 这些基础技术可以大致分为三类 数据填充方式 布局定义方式 以及内容显示方式 查看 WWDC 20 的 《集合视图的发展》讲座 了解所有这些新功能的介绍
本此讲座 我们将重点讨论视图配置 配置单元格内容和样式的新型 API 我们将从基本知识介绍开始 看看如何使用这些新配置 来轻松设置单元格
接下来 我们将深入探讨一个 叫做“配置状态”的新概念 它与配置一起使用 可以轻松在不同状态下获得不同外观
最后我们再来仔细看看这两种配置类型 背景配置和内容配置 并详细介绍这些配置的使用方法 在介绍这些现代单元格配置 API 之前 让我们通过示例快速看一下 如何在 iOS 13 中配置表视图单元格
如果大家以前使用过 UITableView 则应该非常熟悉 在这里 我们使用 UITableViewCell 上的 内置 imageView 和 textLabel 属性 来显示图像和一些文本 这是我们所说的单元格配置的 一个简单示例 考虑到这一点 让我们看一下如何使用新的配置 API 进行相同的操作
这是大家使用内容配置 来配置单元格的方式 看起来与我们之前的非常相似 只是有两行新代码 让我们把任务分解一下 我们要做的第一件事 是向单元格请求 defaultContentConfiguration 该操作将始终返回一个 没有设置任何内容的新配置 但是这个配置有默认的样式 基于单元格和表格视图样式 我们稍后将详细讨论 内容配置的样式和其他功能
现在我们只需在内容配置中 设置图像和文本 这部分大家应该很熟悉 现在我们已经设置好内容 还有最后一步 通过将配置设置为 contentConfiguration 属性 将其应用于单元格 此操作完成后 单元格将更新 以显示我们指定的图像和文本 现在在这行代码之前 设置图像和文本只会更改 存储在此“content”变量中的 配置的本地副本 因为我们使用的是内容配置 我们从不直接接触 UIImageView 或 UILabel 所有属性都在配置本身上设置 那么通过使用内容配置来设置单元格 我们得到了什么 首先 在这里看到的 配置表视图单元格的代码 实际上与任何单元格配置所用的代码 没什么差别 例如集合视图单元格 实际上相同的代码适用于 所有支持内容配置的视图 即使不是单元格 例如表视图页眉和页脚 这是如何实现的? 是因为配置是可组合的 而不是将所有功能都 包含到单元格类本身 就像在 UITableViewCell 中一样 这些标准单元格布局和外观 现在可以作为独立部分使用 可以直接插入到任何适配的 单元格或视图中
让我们运行这段代码 看看效果如何 并了解使用配置所带来的其他好处
这是我们的单元格位于集合视图列表 为多栏 iPad app 使用新的侧边栏外观 你可以看到单元格中 有我们配置的星型图像和文本 现在当我们开始与单元格互动时 事情变得更加有趣 当我触按单元格时 外观会突出显示 当我抬起时 单元格即被选中
但这些只是单元格 可能处于的几种不同状态 所以让我们添加更多的单元格 并手动设置不同的状态 看看单元格的外观如何变化 内容配置相同 但应用于不同状态下的不同单元格 我来换掉这些单元格中的文本 标明每个单元格处于哪种状态
正如大家在这里看到的 侧边栏列表单元格的默认样式 在不同的状态下有很大的不同 通过配置设置单元格 可以自动获得所有这些不同的外观 稍后我们将详细讨论其工作原理
所以我们已经领略了这些新配置 但它们到底是什么
配置描述特定状态视图的外观 比如内容、样式、度量和行为
其本身只是一堆属性 在应用到要渲染的视图或单元格之前 配置不会执行任何操作
正如我们前面已经谈到的 配置是可组合的 可以用于所适配的任何类型的 单元格或视图 现在有两种类型的配置 背景配置和内容配置 让我们看看这两种系统配置 实现的一些功能
背景配置有许多属性 可以让大家快速指定常见的背景外观 只需几行代码 大家就可以自定义背景填充颜色 设置视觉效果来获得漂亮的模糊效果 并添加笔触和一些圆角
如果你想进行更多自定义操作 则可以通过提供自己的视图来实现 列表内容配置为大家提供了单元格 页眉和页脚的标准布局 这与大家现在熟悉的 UITableView 单元格样式非常相似 只是列表内容配置更强大 支持图像、文本和可选的辅助文本 并提供了许多属性供大家自定义 还提供了更高级别的行为 例如灵活的布局以显示更大量的文本 以及用于辅助功能文本大小的 特殊布局模式
这两种配置类型齐头并进 具有一些共同的设计原则
其中一个最重要的原则是轻量级配置 且创建成本非常低廉 属于 Swift 中的值类型 这意味着只要你有配置 都是你自己的 并且你对配置所做的更改 不会影响任何其他内容 直到将该配置设置到单元格上
因为配置是轻量级的 所以大家应该始终从全新的配置开始 例如通过询问单元格的 defaultContentConfiguration 如你在这里看到的 这不仅适用于首次单元格配置 而且适用于希望更新已配置的单元格 每次只需重新配置 然后将其设置为新状态即可 使用配置时 根本不需要考虑旧状态 无需担心是否已经应用旧配置 也无需首先尝试获取现有配置 以对其进行更改 每次只需使用全新配置 按照你想要的方式设置 然后将其应用到单元格即可 如果你已经使用 UIKit 很长时间了 一开始使用可能会让你感觉有点不同 但是一旦你开始以这种方式思考 就会给你带来令人难以置信的解放效果 当你将配置应用到单元格时 UIKit 将为你完成所有繁重的工作 它将找出更改的内容 并根据需要高效地更新视图 正如在前面运行代码时看到的 配置为大家提供了 许多不同状态的默认外观 但是配置也是建立在 强大的基础架构之上的 可用于自定义这些状态的外观 我们将在稍后详细讨论
配置还使大家只需几行代码 即可访问高级行为 假设你要对背景外观进行动画处理 你所要做的就是在动画中 设置一个新的背景配置
配置不仅易于使用 其设计实际上还可以消除所有类型的错误 特别是在处理复杂的状态和转换时 大家一直知道当前应用的配置是真实的 并且当大家设置新配置时 该新配置会立即全部应用
最后 配置从一开始就为性能而构建 这对于确保平滑滚动尤为重要 因为 UIKit 负责管理视图和渲染 所以我们能够在后台 实现许多内部性能优化 而且都是免费的 现在大家已经熟悉了配置的基本知识 下面让我们来探讨一个 与配置一起使用的新概念 称为配置状态
配置状态表示 用于配置单元格和视图的各种输入 我们所谈论的是什么样的输入呢? 决定如何设置视图的最常见输入之一 是来自 UITraitCollection 的 trait 包括诸如大小类、用户界面样式 和内容大小类别的内容 在这些 trait 之上 大家的单元格和视图 以各种不同的状态存在 可能大家的单元格已被选中 或者成为拖放的目标 或者暂时被禁用 这些只是 UIKit 中常见的一些不同状态 在这些状态之上 你的 app 有其本身的自定义状态 大家使用的所有不同状态 对应于你的 app 及其域 例如在配置单元格时 消息 app 可能需要知道 消息是否已存档或标记 而支付 app 可能会显示正在处理的交易 如果使用视图模型向单元格中填充内容 也可以将该视图模型视为自定义状态 所有这些都是构成配置状态的要素 所有不同的特征、状态和你自己的 习惯状态的集合
那么在哪里可以找到配置状态
集合或表视图中的 每个单元格、页眉和页脚 都有自己的配置状态 这里有三个单元格 每个单元格的配置状态可能不同
那么配置状态是什么样的 有两种不同的类型 如大家在此处看到的 视图有一个配置状态类型 比如这个页眉 而单元格有另一种类型
以下是视图配置状态的外观 从 trait 集合开始 然后是四种不同的状态 高亮、选中、禁用和聚焦 这些只是简单的布尔运算
最后我们有可选的自定义状态 这是键值存储 用于添加配置视图时 要使用的任何额外状态或数据
这就是视图配置状态 那单元格配置状态呢?
单元格配置状态 只是获取视图配置状态的所有内容 并添加一些特定于单元格的附加状态 无论单元格正处于编辑、滑动还是展开 以及某些特定于拖放的状态
你可以对配置状态执行的 最重要的操作之一 就是使用它来更新新状态的配置 你可以请求任何背景或内容配置 返回不同配置状态的更新版本 返回的是配置的新副本 并更新其属性以反映新状态
例如背景配置可能更改其背景颜色 内容配置可能更改 图像色调颜色和文本颜色 当大家请求更新配置时 原始配置不会更改 如果你已经在原始配置上自定义任何属性 那么这些属性在更新的配置上将保持不变 设置属性后 可以将其视为已被“锁定” 回想一下本此会话开始时的演示 在演示中 我们看到了内容配置 针对不同状态更新了外观
这是因为自动配置更新
默认情况下 当你在单元格上设置背景或内容配置时 每当单元格的配置状态变化 它将自动要求配置 返回其自身的更新版本 然后将新配置重新应用回单元格 这些属性允许你可以控制此行为
自动更新非常有用 可以为每个状态获取默认样式 但是如果要针对不同状态进行外观自定义 则可以禁用自动更新 并自己更新配置
但是应该把更新这些配置的代码 放在哪里呢?
我们在集合和表视图单元格上 有一个全新的方法 叫做 updateConfiguration(using state:)
这种方法可以在单元格子类中覆写 大家可以在其中放置代码 根据传入的状态配置单元格
此方法始终在单元格首次显示之前调用 并且在配置状态发生变化时将再次调用 因此大家可以自行配置新状态 请记住使用配置时 大家无需担心旧状态 每次只需获得一个全新配置 设置其属性并将其应用到你的单元格
当你的代码中只有一处负责设置配置 并将其应用到你的单元格时 配置才能发挥最佳效果 如果使用的是自定义单元格子类 则此新方法 updateConfiguration(using state:) 是执行此操作的最佳位置 此方法也是将任何其他设置 或更新集中到单元格的好位置 例如 如果使用的是 新的集合视图列表单元格 则可以使用此方法为不同状态 更新单元格附件的淡色调
如果出于任何原因需要重新配置单元格 只需调用 setNeedsUpdate- Configuration 来请求更新
让我们看一个示例 通过示例说明如何使用此方法设置单元格 并手动更新不同状态的配置
首先 通过询问单元格的 defaultContentConfiguration 来获得新的配置 我们将立即将其更新为新状态 这将为我们提供此状态下 系统默认样式的配置
接下来我们将为单元格显示的项目 设置配置的图像和文本
现在我们可以应用我们的定制 在这里我们检查状态 是否被突出显示或选中 如果是 我们将图像和文本颜色设置为白色
对于任何其他状态 我们根本无需设置颜色 这意味着我们使用的是配置的默认颜色
最后 我们为单元格设置新的配置 就是这样 每当状态更改时 将再次调用此方法 并且每次都将为新状态应用新配置
因此这就是你针对不同状态 自定义内容配置外观的方式 我们同样可以在此处自定义背景配置
现在在此示例中 我们在某些状态下为图像 和文本设置不同的颜色 但是有另一种方法 可以改变不同状态下颜色的外观 使用一种叫做颜色转换器的新类型 颜色转换器接受一种颜色 并通过某种方式修改原始颜色 然后返回不同的颜色 例如 你可能有一个颜色转换器 返回颜色的灰度版本
颜色转换器只是一个简单的功能 但是颜色转换器非常强大 因为你可以使用不同的颜色转换器 从相同的输入颜色生成许多不同的变体 这就是如何使用颜色转换器 为不同的状态创建不同外观的方式 某些样式和状态的某些默认配置 将具有预设的颜色转换器 以便为该状态生成特定的外观 颜色转换器与输入颜色相结合 生成大家实际看到的解析颜色
现在大家已经了解了 配置如何为不同的状态生成更新的外观 让我们来讨论背景和内容配置使用时 需要了解的一些细节
集合视图列表单元格、表视图单元格 和表视图页眉和页脚都会 根据包含列表或表视图的样式 自动设置默认背景配置 因此通常情况下 你无需执行任何操作 即可获得所需的背景外观 现在内容配置的工作方式略有不同 与默认情况下自动应用内容的单元格不同 你可以对单元格使用 defaultContentConfiguration 方法 来根据单元格的样式获取新的配置 如大家在前面的示例中所看到的
但是对于背景和内容配置 大家可以通过直接转到 UIBackgroundConfiguration 和 UIListContentConfiguration 类型 轻松地请求任何样式的默认配置 在这里 大家可以在示例中看到 如何对侧边栏样式的列表单元格 执行此操作 对于其他不同样式的单元格、页眉和页脚 也有类似的方法
我们来看看这些不同样式的 实际操作如何?
这里我们有一个标签类别的列表 该列表当前配置了侧边栏外观 因此所有单元格都具有与该样式匹配的 默认背景 和内容配置 大家可以看到当我与单元格交互时 单元格针对不同的状态 更新其背景和内容外观
但是侧边栏样式只是我们 可以用于集合视图列表的外观之一 让我们看看 如果我们用一些不同的外观进行配置 会发生什么 同一个列表 使用分组外观进行配置 这是嵌入的分组外观
是简单的外观 大家可能从 UITableView 中 识别出这些样式
集合视图列表支持一些新样式 例如此侧边栏简单外观 和我们开始时使用的原始侧边栏外观 对于这些不同的列表外观 大家看到的所有视觉样式都来自 默认的背景和内容配置 现在让我们切换回分组样式 这样我们可以更清楚地看到各个单元格 并通过更改系统文本大小设置来查看 它们如何响应不同的动态类型大小 大家可以看到 默认情况下 所有内容都会动态响应这些更改 当我们增加文本大小时 整个布局也会随之调整 如果我们打开最大的辅助功能文本大小 大家会看到单元格布局 使用了一种特殊的模式 其中文本环绕图像 以最大程度地增加内容的可用空间
内容配置是从头开始构建的 以支持这样的动态布局 因此让我们快速了解一下它的工作原理
内容配置设计用于自调整大小的单元格 根据精确的配置和环境 这些单元格的高度可以灵活调整 这对于确保在不同设备尺寸 不同动态类型尺寸 以及不同数量和类型的内容上运行时 app 的良好外观非常重要 利用内容配置 大家可以控制此处以蓝色显示的布局边距 和以橙色显示的 各种填充属性 这些与实际内容一起 决定了单元格的固有高度 并影响了其本身尺寸的调整 大家应该在内容配置上使用这些属性 来影响布局并允许动态调整高度 而不是尝试强制使用固定高度 还有一个布局概念大家应该知道 让我们举个例子看它是如何工作的 在这里我们有三个不同的单元格 每个单元格都使用带有图像 和一些文本的内容配置 现在一切看起来都很好 但是假设我们想在这些单元格中 使用一些不同的图像
问题是图像的大小不完全相同 它们的宽度略有不同 因此各单元格的图像和文本不再对齐 发生这种情况的原因是图像是前导对齐的 文本的位置与每个图像后缘的 填充量相同 为了使这些单元格正确对齐 我们需要为每个图像 指定所谓的保留布局大小
如果我们在每个内容配置上 为图像设置相同的保留布局宽度 那么所做的就是将图像水平居中放置 在该保留空间内 在本图中 两条红色虚线之间的距离 为每个图像的保留布局宽度 保留的布局大小不影响图像的实际大小 如果图像大于保留的布局大小 则可以将其扩展到该区域之外 使用图像的保留布局大小 也可以正确对齐文本 因为文本相对于每个单元格中 图像的相同保留布局区域 进行定位 如果大家使用的是符号图像 UIKit 会自动应用标准的保留布局大小 如果需要 大家可以手动请求非符号图像 这就是大家需要了解的 列表内容配置布局的知识 在开始采用配置时 让我们回顾几个重要的细节
如果大家有正在更新和迁移的现有代码 请记住 配置与某些现有属性 是互斥的
设置背景配置始终 会将背景颜色和背景视图属性重置为零 同样的事情反过来也适用 因此 请确保不要将背景配置与 仍在同一单元格上 设置这些其他背景属性的 其他代码混合使用
特别是对于使用 UITableView 的用户 内容配置将取代单元格、页眉 和页脚的内置子视图 如imageView、textLabel 和 detailTextLabel
这些旧的内容属性将在将来的版本中弃用 因此我们建议大家采用内容配置 以利用其更强大的功能 和增强的可定制性 我们今天介绍的 背景配置和列表内容配置类型 非常强大 但是仍然会有一些时候 你需要做一些定制程度更高的事情 通过配置 大家有了前所未有的更多选择
除了列表内容配置之外 我们还允许大家访问关联的列表内容视图 该视图实现了所有的渲染 大家只需使用配置创建或更新此视图 然后可以将其作为子视图 添加到自己的自定义视图旁边 这样大家就可以利用所有内容配置功能 并将列表内容视图 与旁边的自己的其他自定义视图 例如附加图像视图或标签 组合在一起
而且由于列表内容视图 只是一个普通的 UIView 因此大家实际上可以在任何地方单独使用 甚至在集合或表视图之外 例如在普通 UIStackView 中 但是如果根本不构建列表 或者想实现完全自定义 情况又会怎样呢? 配置可以满足你的需求
即使在单元格中构建 完全自定义的视图层次结构 也可以使用系统配置提供帮助 因为配置是如此轻量级 所以即使大家从未直接应用配置本身 可以将其用作字体、颜色 和边距等默认值的来源 复制到自定义视图中
对于更高级的用例 大家可以使用渲染它的成对内容视图类 创建完全自定义的内容配置类型 然后像使用列表内容配置一样 将你的自定义配置用于任何单元格
通过自定义配置 大家可以利用我们讨论过的所有功能 包括允许自定义配置 针对新状态自动更新 无论大家的单元格复杂 或自定义程度有多高 都可以利用配置的强大功能 我们已经介绍了现代单元格配置的 所有要素 大家已经了解到使用背景 和内容配置非常容易 以及如何使用相同的代码 来配置集合视图单元格或表视图单元格
通过配置 大家可以专注于要显示的内容 而不必担心如何更新所有视图 你只需要每次都从一个新的配置开始 按照你想要的方式设置 然后应用到你的单元格上 让 UIKit 来处理剩下的工作 大家已经了解了如何使用配置状态 更新配置以生成各种不同的外观 以及如何在设置单元格时使用配置状态
我们今天所讨论的所有内容都是 为了满足大家的需要而设计的 是可组合的和可扩展的 因此请下载示例 app 并尝试使用这些新的 API 然后开始使用内容和背景配置 在 app 中设置集合和表格视图单元格吧
请务必查看 WWDC 20 的集合视图对话 了解更多关于构建列表的信息
-
-
1:31 - Configuring a UITableViewCell
cell.imageView?.image = UIImage(systemName: "star") cell.textLabel?.text = "Hello WWDC!"
-
1:59 - Configuring a UITableViewCell Using a Content Configuration
var content = cell.defaultContentConfiguration() content.image = UIImage(systemName: "star") content.text = "Hello WWDC!" cell.contentConfiguration = content
-
13:10 - Updating Configurations
let updatedConfiguration = configuration.updated(for: state)
-
16:33 - Customizing Appearance for Different States
override func updateConfiguration(using state: UICellConfigurationState) { var content = self.defaultContentConfiguration().updated(for: state) content.image = self.item.icon content.text = self.item.title if state.isHighlighted || state.isSelected { content.imageProperties.tintColor = .white content.textProperties.color = .white } self.contentConfiguration = content }
-
19:45 - Default Configurations
var background = UIBackgroundConfiguration.listSidebarCell() var content = UIListContentConfiguration.sidebarCell()
-
26:23 - Creating a List Content View
var content = UIListContentConfiguration.cell() // Set up the content configuration as desired... let contentView = UIListContentView(configuration: content)
-
-
正在查找特定内容?在上方输入一个主题,就能直接跳转到相应的精彩内容。
提交你查询的内容时出现错误。请检查互联网连接,然后再试一次。