IOS 集合视图指南3:设计你的数据源和代理
来源:互联网 发布:西门子编程电缆通讯 编辑:程序博客网 时间:2024/05/17 01:29
Designing Your Data Source and Delegate(设计你的数据源和代理)
Every collection view must have a data source object. The data source object is the content that your app displays. It could be an object from your app’s data model, or it could be the view controller that manages the collection view. The only requirement of the data source is that it must be able to provide information that the collection view needs, such as how many items there are and which views to use when displaying those items.
The delegate object is an optional (but recommended) object that manages aspects related to the presentation of and interaction with your content. Although the delegate’s main job is to manage cell highlighting and selection, it can be extended to provide additional information. For example, the flow layout extends the basic delegate behavior to customize layout metrics, such as the size of cells and the spacing between them.
The Data Source Manages Your Content(数据源控制你的内容)
The data source object is the object responsible for managing the content you are presenting using a collection view. The data source object must conform to the UICollectionViewDataSource
protocol, which defines the basic behavior and methods that you must support. The job of the data source is to provide the collection view with answers to the following questions:
How many sections does the collection view contain?
For a given section, how many items does a section contain?
For a given section or item, what views should be used to display the corresponding content?
- 集合视图内容有多少节
- 每一节有多少元素呢
- 每一节或者元素该怎样展现相应的内容呢?
Sections and items are the fundamental organizing principle for collection view content. A collection view typically has at least one section and may contain more. Each section, in turn, contains zero or more items. Items represent the main content you want to present, whereas sections organize those items into logical groups. For example, a photo app might use sections to represent a single album of photos or a set of photos taken on the same day.
NSIndexPath
objects. When trying to locate an item, the collection view uses the index path information provided to it by the layout object. For items, the index path contains a section number and an item number. For supplementary and decoration views, the index path contains whichever values were provided by the layout object. The meaning of the index paths attached to supplementary and decoration views is dependent on your app, though the first index corresponds to a specific section in the data source. These views’ index paths are more about identification than meaning, identifying which view of what kind is currently being considered. So, if for example you have supplementary views that create headers and footers for your sections as seen in the flow layout, the relevant information provided by the index path is the section referenced.Note: Although standard index paths support multiple levels, the collection view’s cells only supports index paths that are 2-levels deep with “section” and “item” parameters, much like the index paths for the UITableView
class. Supplementary views and decoration views can have more complex index paths if necessary. Elements whose index paths are > 1 is interpreted to correspond to the section designated by the first index in the path. Traditionally, only a second index is necessary, but supplementary and decoration views are not restricted to just two. Keep this in mind when designing your data source.
Sections arranged according to the arrangement of layout objects
Designing Your Data Objects(设计你的数据对象)
An efficient data source uses sections and items to help organize its underlying data objects. Organizing your data into sections and items makes it much easier to implement your data source methods later. And because your data source methods are called frequently, you want to make sure that your implementations of those methods are able to retrieve data as quickly as possible.
One simple solution (but certainly not the only solution) is for your data source to use a set of nested arrays, as shown in Figure 2-2. In this configuration, a top-level array contains one or more arrays representing the sections of your data source. Each section array then contains the data items for that section. Finding an item in a section is a matter of retrieving its section array and then retrieving an item from that array. This type of arrangement makes it easy to manage moderately sized collections of items and retrieve individual items on demand.
一个有效的数据源使用节和元素来帮助组织基础的数据对象。把你的数据按照节和元素来组织可以更轻松的完成数据源中的方法。因为你的数据源方法被频繁的调用,你要确定你实现的那些方法能够尽可能快的取回数据。
一个简单的解决方案是(绝对不是唯一的方案啊)把你的数据源组织成一个嵌套数组,就像图2-2展示的一样。在这种配置中,最外层数据包含一个或多个数据展示你数据源中的节。每一节数据包含属于这一节的数据项。找到一个节中的数据项就是先取出节数组,在节数组中取出数据项。这种形式的安排可以让管理集合中的数据项更方便,同时更容易按照要求取出单个的数据项。Arranging data objects using nested arrays
When designing your data structures, you can always start with a simple set of arrays and move to a more efficient structure as needed. In general, your data objects should never be a performance bottleneck. The collection view usually accesses your data source only to calculate how many objects there are in total and to obtain views for elements that are currently onscreen. If the layout object relies only on data from your data objects, performance could be severely impacted when the data source contains thousands of objects.
当设计你的数据结构的时候,你可以从设置一个简单的数组开始然后根据需要添加有效的数据结构。通常,你的数据对象不应该是一个性能瓶颈。集合视同通访问你的数据源仅仅通过计算一共有多少元素,并且获取当前屏幕需要的数据对象。如果布局对象只依赖于你的数据对象的话,当你的数据对象包含上千条数据的时候性能就会受到大幅度影响。
Telling the Collection View About Your Content(告诉集合视图关于你的内容)
Among the questions asked of your data source by the collection view are how many sections it contains and how many items each section contains. The collection view asks your data source to provide this information when any of the following actions occur:
The collection view is displayed for the first time.
You assign a different data source object to the collection view.
You explicitly call the collection view’s
reloadData
method.The collection view delegate executes a block using
performBatchUpdates:completion:
or any of the move, insert, or delete methods.
- 集合视图第一次展示的时候
- 你给集合视图指定了一个不同的数据源的时候
- 你明确要求集合视图调用reloadData方法的时候
- 集合视图代理执行performBatchUpdates:completion:使用的代码块的时候,或者任何移动,插入,或者删除方法执行的时候。
You provide the number of sections using the numberOfSectionsInCollectionView:
method, and the number of items in each section using the collectionView:numberOfItemsInSection:
method. You must implement the collectionView:numberOfItemsInSection:
method, but if your collection view has only one section, implementing the numberOfSectionsInCollectionView:
method is optional. Both methods return integer values with the appropriate information.
If you implemented your data source as shown in Figure 2-2, the implementation of your data source methods could be as simple as those shown in Listing 2-1. In this code, the _data
variable is a custom member variable of the data source that stores the top-level array of sections. Obtaining the count of that array yields the number of sections. Obtaining the count of one of the subarrays yields the number of items in the section. (Of course, your own code should do whatever error checking is needed to ensure that the values returned are valid.)
你使用numberOfSectionsInCollectionView:来提供节的数目,用collectionView:numberOfItemsInSection:方法来提供每节的数据项数目。你必须实现collectionView:numberOfItemsInSection:
方法,但是如果你的集合视图只有一节, numberOfSectionsInCollectionView:
方法就可以选择实现。这两个方法的返回值都是integer类型的。
如果你像图2-2那样实现你的数据源,那么你就可以像列表2-1那样简单的实现数据源方法,这些代码中,_data是保存着数据源的节的定义数组的自定义成员变量。获得数组中节的数据 ,获取子数组中数据项的数目。(当然你的代码中应该做足错误检查以确保你的返回值是可用的)。
Providing the section and item counts
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView*)collectionView {
// _data is a class member variable that contains one array per section.
return [_data count];
}
- (NSInteger)collectionView:(UICollectionView*)collectionView numberOfItemsInSection:(NSInteger)section {
NSArray* sectionArray = [_data objectAtIndex:section];
return [sectionArray count];
}
Configuring Cells and Supplementary Views(配置单元格和增补视图)
Another important task of your data source is to provide the views that the collection view uses to display your content. The collection view does not track your app’s content. It simply takes the views you give it and applies the current layout information to them. Therefore, everything that is displayed by the views is your responsibility.
After your data source reports how many sections and items it manages, the collection view asks the layout object to provide layout attributes for the collection view’s content. At some point, the collection view asks the layout object to provide the list of elements in a specific rectangle (often this is the visible rectangle). The collection view uses that list to ask your data source for the corresponding cells and supplementary views. To provide those cells and supplementary views, your code must do the following:
Embed your template cells and views in your storyboard file. (Alternatively, register a class or nib file for each type of supported cell or view.)
In your data source, dequeue and configure the appropriate cell or view when asked.
- 把你的模板单元格和增补视图嵌入你的故事版中(或者,为每种单元格和视图注册一个类或者nib文件)。
- 在你的数据源中,在请求的时候列出合适的单元格并设置。
To ensure that cells and supplementary views are used in the most efficient way possible, the collection view assumes the responsibility of creating those objects for you. Each collection view maintains internal queues of currently unused cells and supplementary views. Instead of creating objects yourself, simply ask the collection view to provide you with the view you want. If one is waiting on a reuse queue, the collection view prepares it and returns it to you quickly. If one is not waiting, the collection view uses the registered class or nib file to create a new one and return it to you. Thus, every time you dequeue a cell or view, you always get a ready-to-use object.
Reuse identifiers make it possible to register multiple types of cells and multiple types of supplementary views. A reuse identifier is a string that you use to distinguish between your registered cell and view types. The contents of the string are relevant only to your data source object. But when asked for a view or cell, you can use the provided index path to determine which type of view or cell you might want and then pass the appropriate reuse identifier to the dequeue method.
Registering Your Cells and Supplementary Views(注册你的单元格和增补视图)
You can configure the cells and views of your collection view programmatically or in your app’s storyboard file.
Configure cells and views in your storyboard. When configuring cells and supplementary views in a storyboard, you do so by dragging the item onto your collection view and configuring it there. This creates a relationship between the collection view and the corresponding cell or view.
For cells, drag a Collection View Cell from the object library and drop it on to your collection view. Set the custom class and the collection reusable view identifier of your cell to appropriate values.
For supplementary views, drag a Collection Reusable View from the object library and drop it on to your collection view. Set the custom class and the collection reusable view identifier of your view to appropriate values.
- 对于单元格,从对象库中拖拽一个Collection View Cell 把它放到你的集合视图上。设置自定义类同时为你的单元格设置合适的复用视图标识。
- 对于增补视图,从对象库中拖拽一个Collection Reusable View把它放在你的集合视图上。设置自定义类同时为你的视图设置合适的复用视图标识。
Configure cells programmatically. Use either the registerClass:forCellWithReuseIdentifier:
or registerNib:forCellWithReuseIdentifier:
method to associate your cell with a reuse identifier. You might call these methods as part of the parent view controller’s initialization process.
Configure supplementary views programmatically. Use either the registerClass:forSupplementaryViewOfKind:withReuseIdentifier:
orregisterNib:forSupplementaryViewOfKind:withReuseIdentifier:
method to associate each kind of view with a reuse identifier. You might call these methods as part of the parent view controller’s initialization process.
Although you register cells using only a reuse identifier, supplementary views require that you specify an additional identifier known as a kind string. Each layout object is responsible for defining the kindsof supplementary views it supports. For example, the UICollectionViewFlowLayout
class supports two kinds of supplementary views: a section header view and a section footer view. To identify these two types of views, it defines the string constants UICollectionElementKindSectionHeader
and UICollectionElementKindSectionFooter
. During layout, the layout object includes the kind string with the other layout attributes for that view type. The collection view then passes the information along to your data source. Your data source then uses both the kind string and the reuse identifier to decide which view object to dequeue and return.
registerNib:forCellWithReuseIdentifier:
方法让你的单元格和复用标识发生联系。你可以在调用这些方法作为父视图控制器初始化的一部分。registerClass:forSupplementaryViewOfKind:withReuseIdentifier:
方法或registerNib:forSupplementaryViewOfKind:withReuseIdentifier: 方法让你的视图和你的复用标识发生联系。你可以在调用这些方法作为父视图控制器初始化的一部分。UICollectionElementKindSectionHeader
和UICollectionElementKindSectionFooter
.。在布局中,布局对象包含了类型字符串和其他视图类型的布局属性。之后结合视图会把信息发送至你的数据源,你的数据源之后会使用这两种字符串和复用标识符来决定哪个视图对象会出列并返回。Note: If you implement your own custom layouts, you are responsible for defining the kinds of supplementary views your layout supports. A layout may support any number of supplementary views, each with its own kind string. For more information about defining custom layouts, see Creating Custom Layouts.
提示:如果你实现了你的自定义布局,你要负责定义你的布局对象支持的增补视图类型。一个布局可能支持多种增补视图,每种都有响应的字符串。更多关于定义自定义布局的信息,请见:《Creating Custom Layouts》。
Registration is a one-time event that must take place before you attempt to dequeue any cells or views. After you’ve registered, you can dequeue as many cells or views as needed without reregistering them. It’s not recommended that you change the registration information after dequeueing one or more items. It is better to register your cells and views once and be done with it.
注册是一次性事件所以必须发生在你尝试列出单元格或视图之前。你注册之后,你可以根据需要列出很多单元格或视图而不再去注册他们。不建议你在列出项之后更改注册信息。最好的办法就是你注册单元格,然后就用它。
Dequeueing and Configuring Cells and Views(列出并设置单元格和视图)
Your data source object is responsible for providing cells and supplementary views when asked for them by the collection view. The UICollectionViewDataSource
protocol contains two methods for this purpose: collectionView:cellForItemAtIndexPath:
and collectionView:viewForSupplementaryElementOfKind:atIndexPath:
. Because cells are a required element of a collection view, your data source must implement the collectionView:cellForItemAtIndexPath:
method, but the collectionView:viewForSupplementaryElementOfKind:atIndexPath:
method is optional and dependent on the type of layout in use. In both cases, your implementation of these methods follows a very simple pattern:
Dequeue a cell or view of the appropriate type using the
dequeueReusableCellWithReuseIdentifier:forIndexPath:
ordequeueReusableSupplementaryViewOfKind:withReuseIdentifier:forIndexPath:
method.Configure the view using the data at the specified index path.
Return the view.
UICollectionViewDataSource
协议包含了两种实现这种目的的方法collectionView:cellForItemAtIndexPath::和collectionView:viewForSupplementaryElementOfKind:atIndexPath:
.。因为单元格是集合视图需要的一个元素,你的数据源必须完成collectionView:cellForItemAtIndexPath:
方法,但是collectionView:viewForSupplementaryElementOfKind:atIndexPath:
方法是可选的,选择依据使用的布局类型。在两种情况下,你可以用非常简单的模式实现这些方法:- 列出合适类型的单元格或视图用如下方法:
dequeueReusableCellWithReuseIdentifier:forIndexPath:
或dequeueReusableSupplementaryViewOfKind:withReuseIdentifier:forIndexPath:
- 使用指定路径的数据来设置的视图
- 返回视图。
The dequeueing process is designed to relieve you of the responsibility of having to create a cell or view yourself. As long as you registered a cell or view previously, the dequeue methods are guaranteed to never return nil
. If there is no cell or view of the given type on a reuse queue, the dequeue method simply creates one using your storyboard or using the class or nib file you registered.
The cell returned to you from the dequeueing process should be in a pristine state and ready to be configured with new data. For a cell or view that must be created, the dequeueing process creates and initializes it using the normal processes—that is, by loading the view from a storyboard or nib file or by creating a new instance and initializing it using the initWithFrame:
method. In contrast, an item that wasn’t created from scratch but that was instead retrieved from a reuse queue may already contain data from a previous usage. In that case, dequeue methods call the prepareForReuse
method of the item to give it a chance to return itself to a pristine state. When you implement a custom cell or view class, you can override this method to reset properties to default values and perform any additional cleanup.
After your data source dequeues the view, it configures the view with its new data. You can use the index path passed to your data source methods to locate the appropriate data object and then apply that object’s data to the view. After you configure the view, return it from your method and you are done. Listing 2-2 shows a simple example of how to configure a cell. After dequeueing the cell, the method sets the cell’s custom label using the information about the cell’s location and then returns the cell.
Configuring a custom cell
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath {
MyCustomCell* newCell = [self.collectionView dequeueReusableCellWithReuseIdentifier:MyCellID
forIndexPath:indexPath];
newCell.cellLabel.text = [NSString stringWithFormat:@"Section:%d, Item:%d", indexPath.section, indexPath.item];
return newCell;
}
Note: When returning views from your datasource, always return a valid view. Returning nil
, even if for some reason the view that is being asked for should not be displayed, causes an assertion and your app terminates because the layout object expects valid views to be returned by these methods.
- IOS 集合视图指南3:设计你的数据源和代理
- IOS 集合视图指南2:集合视图基础
- IOS 集合视图指南2:集合视图基础
- iOS之 UITableView 的数据源方法和代理方法总结
- iOS视图控制器编程指南 --- 定义你的子类
- IOS 集合视图指南1:介绍
- IOS 集合视图指南5:集合手势支持
- IOS“吐司”和 代理的设计模式
- iOS视图控制器编程指南 --- 设计建议
- 你真的了解iOS代理设计模式吗?
- 你真的了解iOS代理设计模式吗?
- 你真的了解iOS代理设计模式吗?
- 你真的了解iOS代理设计模式吗?
- 你真的了解iOS代理设计模式吗?
- 你真的了解iOS代理设计模式吗?
- 你真的了解iOS代理设计模式吗?
- 你真的了解iOS代理设计模式吗?
- iOS集合视图单元格高亮和选中的区别
- html5 上传图片并显示
- ListView卡顿问题解决
- 通用型CRM还是行业型CRM?-定制为王
- 安卓按返回键让App常驻内存
- 二值图膨胀、腐蚀、开操作和闭操作的实现
- IOS 集合视图指南3:设计你的数据源和代理
- Linux串口测试程序
- Axis和CXF的比较
- Java基础班第一天--面向过程
- highcharts 图表插件
- 如何将项目部署到tomcat下的wtpwebapps目录下
- Coredata之NSPredicate
- android在一个app程序中,打开另一个app的方法
- java生成MD5码的例子