在Swift中使用UICollectionView构建列表

这篇博客介绍了如何在Swift编程环境中利用UICollectionView来创建和管理列表展示内容,详细讨论了相关步骤和技巧。
摘要由CSDN通过智能技术生成

This article is originally published at https://swiftsenpai.com on July 25, 2020.

本文最初于 2020年7月25日 发布在 https://swiftsenpai.com 上。

Since the introduction of UICollectionView in iOS6, UICollectionView has been the default component to go to when it comes to building a grid layout. In WWDC 2020, Apple pushes the usability of UICollectionView to the next level by introducing the list layout in UICollectionView.

自从UICollectionView中引入UICollectionView以来, UICollectionView一直是构建网格布局时要使用的默认组件。 在WWDC 2020中,Apple通过在UICollectionView引入列表布局,将UICollectionView的可用性UICollectionView了新的高度。

By using the new features and APIs given to UICollectionView in iOS14, it is now super easy to build a UITableView-like list, making it arguably the better option when compared to UITableView.

通过使用UICollectionView中提供给UICollectionView的新功能和API,现在可以轻松构建类似UITableView的列表,因此与UITableView相比,它无疑是更好的选择。

In this article, let’s look at how simple it is to create a list with a swipeable cell that displays image and text using the new UICollectionView in iOS 14.

在本文中,让我们看一下使用iOS 14中新的UICollectionView创建具有可滑动显示单元格以显示图像和文本的列表的简单性。

示例应用 (The Sample App)

Before we get started, let’s take a quick look on what kind of list we are trying to build in this article.

在开始之前,让我们快速看一下我们试图构建哪种列表。

Building a List with UICollectionView in Swift
The sample app we going to build
我们将要构建的示例应用程序

As you can see from the above animated gif, we will create an app that displays a list of where when you tap on it, it will show the SFSymbol's name in an UIAlertController.

正如你可以从上面的gif动画看到,我们将创建一个应用程序,显示当你点一下其中的列表,它会显示SFSymbol在的名字UIAlertController

Furthermore, the cells of the list are also swipeable and will trigger its corresponding swipe action when tapped.

此外,列表的单元格也是可滑动的,在点击时将触发其相应的滑动动作。

With all that being said, let’s fire up your Xcode and dive right into it!

话虽如此,让我们启动Xcode并深入其中!

建立清单 (Creating a List)

In order to create a list using UICollectionView, we need to:

为了使用UICollectionView创建列表,我们需要:

  1. Define data identifier type

    定义数据标识符类型
  2. Define section identifier type

    定义节标识符类型
  3. Create a collection view with list layout

    创建具有列表布局的集合视图
  4. Define how data is shown using cell registration

    定义如何使用单元格注册显示数据
  5. Define the collection view’s data source

    定义集合视图的数据源
  6. Create and apply a snapshot to the data source

    创建快照并将快照应用于数据源

1.定义项目标识符类型 (1. Define Item Identifier Type)

Before we start working on the collection view, we must first get ready with our data model. Let’s go ahead and create a SFSymbolItem struct which consists of a name and image constant.

在开始使用集合视图之前,我们必须首先准备好数据模型。 让我们继续创建一个SFSymbolItem结构,该结构由nameimage常量组成。

Make sure to conform the SFSymbolItem struct to the Hashable protocol because the diffable data source (introduced in iOS13) that we are going to use requires unique hash values of the item identifiers.

确保SFSymbolItem结构符合Hashable协议,因为我们将要使用的可扩散数据源(在iOS13中引入)需要项标识符的唯一哈希值。

After that, let’s populate an array of SFSymbolItem so that later we can use it as the data model of our collection view.

之后,让我们填充一个SFSymbolItem数组,以便以后我们可以将其用作集合视图的数据模型。

2.定义节标识符类型 (2. Define Section Identifier Type)

Even though there is only 1 section in our sample app, defining a section is still required. The common approach to define a section identifier is by using an enum.

即使示例应用程序中只有1个部分,仍然需要定义一个部分。 定义节标识符的常用方法是使用枚举。

Usually, the section identifier will only be used in 1 particular view controller, thus it is advisable to define it within the view controller that it is being used.

通常,段标识符将仅在1个特定的视图控制器中使用,因此建议在视图控制器中使用它来定义它。

3.使用列表布局创建集合视图 (3. Create a Collection View with List Layout)

With both item and section identifier in place, we are now ready to work on the collection view. First, let’s define a UICollectionView instance variable.

有了项目和部分标识符,我们现在就可以在集合视图上工作了。 首先,让我们定义一个UICollectionView实例变量。

var collectionView: UICollectionView!

After that, head over to your view controller’s viewDidLoad() and create a collection view with a list-style layout.

之后,转到视图控制器的viewDidLoad()并使用列表样式的布局创建一个集合视图。

One thing to note from the above sample code is that you will need to choose the collection view list appearance when creating a list configuration.

上面的示例代码要注意的一件事是,在创建列表配置时,您将需要选择集合视图列表外观。

In iOS 14, Apple introduced 5 types of appearances that mimicked the appearance of a UITableView. Here are the screenshots of our sample app in different types of appearances.

在iOS系统14,苹果推出了5种类型的外观是模仿一个外观UITableView 。 这是我们的示例应用程序在不同类型的外观中的屏幕截图。

UICollectionView list appearance (grouped, insetGrouped, plain)
Collection view list appearance (grouped, insetGrouped, plain)
集合视图列表外观(分组,insetGrouped,普通)
UICollectionView list appearance (sidebar, sidebarPlain)
Collection view list appearance (sidebar, sidebarPlain)
集合视图列表外观(侧边栏,侧边栏普通)

4.定义如何使用细胞注册显示数据 (4. Define How Data Is Shown Using Cell Registration)

Next up, we will use the new UICollectionView.CellRegistration API introduced in iOS 14 to create a cell registration that defines how data should be shown in a cell.

接下来,我们将使用iOS 14中引入的新UICollectionView.CellRegistration API创建一个单元格注册,该注册定义了应如何在单元格中显示数据。

First, we create a cell registration for cells of type UICollectionViewListCell and data items of type SFSymbolItem.

首先,我们创建类型的细胞的细胞登记UICollectionViewListCell和类型的数据项SFSymbolItem

Inside the cell registration handler, we create a default cell content configuration and use it to specify how we want the data (content) to be shown. After that, we will assign the content configuration to the cell.

在单元格注册处理程序内,我们创建一个默认的单元格内容配置,并使用它来指定我们如何显示数据(内容)。 之后,我们将内容配置分配给单元。

5.定义集合视图的数据源 (5. Define the Collection View’s Data Source)

With the cell registration in place, we can use it to define the data source of our collection view.

有了单元格注册后,我们可以使用它来定义我们的集合视图的数据源。

First, let’s define a UICollectionViewDiffableDataSource instance variable with Section as the section identifier type and SFSymbolItem as the item identifier type.

首先,让我们定义一个UICollectionViewDiffableDataSource实例变量,其中Section为节标识符类型,而SFSymbolItem为项目标识符类型。

var dataSource: UICollectionViewDiffableDataSource<Section, SFSymbolItem>!

Next, head back to viewDidLoad() and create a data source by passing in our collection view and implementing a cell provider closure. Doing this will connect the data source with our collection view.

接下来,返回viewDidLoad()并通过传入我们的集合视图并实现单元提供程序闭包来创建数据源。 这样做会将数据源与我们的集合视图连接起来。

Within the cell provider closure, we dequeue a reusable cell using the cell registration that we created previously. Note that we no longer need to use a cell reuse identifier in order to dequeue a reusable cell. How cool is that? 🥳

在单元提供程序闭合中,我们使用之前创建的单元注册来使可重用单元出队。 请注意,我们不再需要使用单元重用标识符来使可重用单元出队。 多么酷啊? 🥳

Furthermore, the cell provider closure is also a good place for you to configure the cell appearance such as adding cell accessories or changing the cell’s tint color.

此外,单元格提供程序的关闭也是配置单元格外观(例如添加单元格附件或更改单元格的颜色)的好地方。

6.创建快照并将其应用于数据源 (6. Create and Apply a Snapshot to the Data Source)

In this final step, we will tell our view controller what data to show by using the NSDiffableDataSourceSnapshot introduced in iOS 13.

在最后一步,我们将使用iOS 13中引入的NSDiffableDataSourceSnapshot告诉视图控制器要显示哪些数据。

As usual, let’s first create an NSDiffableDataSourceSnapshot instance variable. Make sure to set the section identifier type and item identifier type correctly.

与往常一样,让我们​​首先创建一个NSDiffableDataSourceSnapshot实例变量。 确保正确设置部分标识符类型和项目标识符类型。

var snapshot: NSDiffableDataSourceSnapshot<Section, SFSymbolItem>!

After that, head back to viewDidLoad() and add in the following code snippet.

之后,回到viewDidLoad()并添加以下代码片段。

In the above code, we first create a snapshot instance, and then we let the snapshot know that it should contain the main section and the main section should contain dataItems we defined in step 1. After that, apply the snapshot to the data source to show the data on the collection view.

在上面的代码中,我们首先创建一个快照实例,然后让快照知道它应该包含main部分,并且main部分应该包含我们在步骤1中定义的dataItems 。之后,将快照应用于数据源在集合视图上显示数据。

That’s it for creating a list using a collection view. Go ahead and run the sample code to see the list layout in action.

这就是使用集合视图创建列表的过程。 继续并运行示例代码,以查看实际的列表布局。

处理单元点击动作 (Handling Cell Tap Action)

In this section, we will look into how to handle the cell tap action. As a recap, we will display the selected SFSymbol's name in an UIAlertController as shown in the image below.

在本节中,我们将研究如何处理单元轻拍动作。 作为回顾,我们将显示所选择的SFSymbol在的名字UIAlertController如下所示在图像中。

Handling cell tap action in UICollectionView with list layout
Show an alert after tap on cell
点击单元格后显示警报

As you may have guessed, in order to handle the cell tap action, we will need to implement the collectionView(_:didSelectItemAt:) delegate method. But before that, make sure to set the view controller as the collection view's delegate.

您可能已经猜到了,为了处理单元格轻拍操作,我们将需要实现collectionView(_:didSelectItemAt:)委托方法。 但在此之前,请确保将视图控制器设置为集合视图的委托。

collectionView.delegate = self

Here’s the implementation of the collectionView(_:didSelectItemAt:) delegate method.

这是collectionView(_:didSelectItemAt:)委托方法的实现。

The above code is pretty much self explanatory. However, one thing to note is that we are retrieving the selected data directly from dataSource and not from dataItems.

上面的代码很容易解释。 但是,要注意的一件事是,我们是直接从dataSource而不是dataItems检索选定的数据。

This is very important because UICollectionViewDiffableDataSource might perform some background operation causing dataItems inconsistent with the data being displayed in the collection view.

这非常重要,因为UICollectionViewDiffableDataSource可能会执行某些后台操作,从而导致dataItems与集合视图中显示的dataItems不一致。

处理滑动动作 (Handling Swipe Action)

Handling swipe action in UICollectionView with list layout
Actions when swipe cell from right to left
从右向左滑动单元格时的动作

In order to enable swipe action on our list, let’s scroll back up to the beginning of viewDidLoad() and modify the layoutConfig by defining its trailingSwipeActionsConfigurationProvider. Make sure to change the definition of layoutConfig from let to var.

为了使我们的名单上划动作,让我们向上滚动网页的开头viewDidLoad()和修改layoutConfig通过定义trailingSwipeActionsConfigurationProvider 。 确保将layoutConfig的定义从let更改为var

Pro tip:

专家提示:

Implement leadingSwipeActionsConfigurationProvider to enable the left-to-right swipe action.

实现 leadingSwipeActionsConfigurationProvider 以启用从左到右的滑动动作。

Based on Apple documentation, the trailingSwipeActionsConfigurationProvider is a closure that accepts an IndexPath and returns a UISwipeActionsConfiguration.

根据苹果的文档 ,该trailingSwipeActionsConfigurationProvider是接受一个封闭IndexPath并返回一个UISwipeActionsConfiguration

The following sample code demonstrates how to implement the trailingSwipeActionsConfigurationProvider in order to get our sample app behavior.

以下示例代码演示了如何实现trailingSwipeActionsConfigurationProvider以获得示例应用行为。

Inside the trailingSwipeActionsConfigurationProvider closure, we:

trailingSwipeActionsConfigurationProvider闭包内,我们:

  1. Retrieve the swiped cell’s data item from the data source, just like what we did in collectionView(_:didSelectItemAt:).

    就像我们在collectionView(_:didSelectItemAt:)所做的一样,从数据源中检索已擦除单元格的数据项。

  2. Define the first action (action 1) by creating an instance of UIContextualAction. During the initialization, we set the action's style, title, and implement the action handler.

    通过创建UIContextualAction的实例来定义第一个动作(动作1)。 在初始化期间,我们设置动作的样式,标题,并实现动作处理程序。

  3. Inside the action handler, call the handleSwipe(for:item:) function to show an alert message. We will be implementing this shortly.

    在动作处理程序内,调用handleSwipe(for:item:)函数以显示警报消息。 我们将在短期内实施。

  4. Call the action handler’s completion handler to indicate that we have performed the action.

    调用动作处理程序的完成处理程序以指示我们已执行了该动作。
  5. Configure the action view background color.

    配置操作视图背景颜色。
  6. Define the second action and implement its action handler.

    定义第二个动作并实现其动作处理程序。
  7. Create a swipe action configuration using all the UIContextualAction we just created and return it to the swipe action configuration provider.

    使用我们刚刚创建的所有UIContextualAction创建滑动动作配置,并将其返回到滑动动作配置提供程序。

Lastly, let’s implement the handleSwipe(for:item:) function.

最后,让我们实现handleSwipe(for:item:)函数。

With that, we have completed the sample app implementation. Go ahead and run your sample project to see everything in action.

至此,我们完成了示例应用程序的实现。 继续并运行您的示例项目,以查看运行中的所有内容。

I have uploaded the full sample project to Github, feel free to download it if you need any references.

我已将完整的示例项目上传到Github ,如果需要任何参考,请随时下载。

结语 (Wrapping Up)

The topics being covered in this article has barely scratched the surface of what you can do with a list created using UICollectionView. There are still other more advanced topics such as multi-section list, custom cell configuration, cell reordering, and expandable cells that we yet to explore.

本文涵盖的主题几乎没有涉及使用UICollectionView创建的列表可以做的UICollectionView 。 还有其他更高级的主题,例如多节列表,自定义单元格配置,单元格重新排序和可扩展单元格,我们尚待探讨。

If you would like to get notified when I publish new articles related to these topics, feel free to follow me on Twitter.

如果您希望在我发布与这些主题相关的新文章时得到通知,请随时在Twitter上关注我。

Thanks for reading. 🧑🏻‍💻

谢谢阅读。 ‍💻

相关的WWDC视频 (Related WWDC Videos)

翻译自: https://levelup.gitconnected.com/building-a-list-with-uicollectionview-in-swift-8cbed6aa6080

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值