一、概述

UICollectionView是一个调集视图,是许多不同方针之间的协作。

UICollectionView 基础知识

  • 办理者(UICollectionViewController) 与 容器(UICollectionView)

    • UICollectionView :方针界说调集视图内容的可见区域。继承UIScrollView,能够依据需求包含一个大的可翻滚区域。能够经过layout布局方针接纳的布局信息来表明数据。
    • UICollectionViewController:方针为调集视图供给视图控制器级别的办理支撑。它的运用是可选的。
  • UICollectionReusableView 调集视图中显现的一切视图有必要是UICollectionReusableView类的实例,该类支撑调集视图运用的回收机制。循环视图(而不是创立新视图)总体上提高了功能,尤其是在翻滚期间。 调集视图中布置三种类型的视觉元素:

    • 1、UICollectionViewCell 是用于首要数据项的特定类型的可重用视图。

    • UICollectionView 基础知识

      • 1.1、UICollectionViewListCell (供给列表特性和默许样式的调集视图单元格。 iOS 14+)
    • 2、Supplementary views : 弥补视图,能够运用弥补视图来完结给定部分或整个UICollectionView的header和页footer 视图。辅佐视图是可选的,它们的运用和放置由布局方针界说

    • 3、Decoration views装修视图是完全由布局方针(Layout)具有的视觉装修,与 数据源方针中的任何数据无关。例如,布局方针或许运用装修视图来完结自界说布景外观(每个section的布景外观)。

  • Data:

    • 1、UICollectionViewDiffableDataSource ( iOS 13.0+)

      • 用于办理数据和为调集视图供给单元格的方针。
    • 2、UICollectionViewDataSourcePrefetching

      • 一种协议,为调集视图供给数据需求的预先警告,答应触发异步数据加载操作。
    • 3、 UICollectionViewDataSource 数据源方针,有必要供给的方针

      • 数据源方针是与调集视图相相关的最重要的方针,也是您有必要供给的方针。数据源办理调集视图的内容,并创立显现该内容所需的视图。要完结数据源方针,有必要创立一个契合UICollectionViewDataSource 协议 的方针。
  • Delegate:

    • UICollectionViewDelegate 托付方针,是可选的

      • 调集视图托付方针答应您从调集视图中截取感兴趣的音讯,并自界说视图的行为。例如,运用署理方针来盯梢调集视图中项目的挑选和高亮显现。与数据源方针不同,托付方针是可选的
    • UICollectionViewDragDelegate

      • 初始化从调集视图拖动的接口。
    • UICollectionViewDropDelegate

      • 用于处理调集视图中的拖放的接口。
  • Layout

    • UICollectionViewLayout (布局方针)

      • UICollectionViewLayout的子类作为布局方针,负责界说调集视图中单元格和可重用视图的方位、巨细和视觉特点

      • UICollectionViewFlowLayout 流布局

        • UICollectionViewFlowLayout类是一个具体的布局方针,用于完结网格或其他依据行的布局。您能够按原样运用该类,也能够将其与流托付方针结合运用,这样能够动态自界说布局信息。
      • UICollectionViewCompositionalLayout 组合布局

        • UICollectionViewLayout的子类,是调集视图布局的一种类型,可组合、灵敏和快速的,经过将每个较小的组件组合或合成到一个完好的布局中,能够为内容构建任何类型的视觉摆放。组合布局由一个或多个部分组成,这些部分将布局分解为不同的视觉分组。每个部分都由一组独自的项目组成,这些项目是您想要呈现的最小数据单元。一个组能够将其项目摆放在水平行、笔直列或自界说摆放中。
      • UICollectionViewTransitionLayout

        • UICollectionViewTransitionLayout 一种特别类型的布局方针,用于在调集视图中从一种布局更改为另一种布局时完结行为。
    • UICollectionViewLayoutAttributes(布局特点)

      • 在布局进程中,布局方针会创立布局特点方针(UICollectionViewLayoutAttributes类的实例),告知调集视图在何处以及如何显现单元格和可重用视图
    • UICollectionViewUpdateItem

      • 每当在调集视图中刺进、删去或移动数据项时,布局方针都会接纳UICollectionViewUpdateItem类的实例。您永远不需求自己创立此类的实例。

二、UICollectionView

2.1、枚举
typedef NS_OPTIONS(NSUInteger, UICollectionViewScrollPosition) {
    UICollectionViewScrollPositionNone                 = 0,
    // The vertical positions are mutually exclusive to each other, but are bitwise or-able with the horizontal scroll positions.
    // Combining positions from the same grouping (horizontal or vertical) will result in an NSInvalidArgumentException.
    UICollectionViewScrollPositionTop                  = 1 << 0,
    UICollectionViewScrollPositionCenteredVertically   = 1 << 1,
    UICollectionViewScrollPositionBottom               = 1 << 2,
    // Likewise, the horizontal positions are mutually exclusive to each other.
    UICollectionViewScrollPositionLeft                 = 1 << 3,
    UICollectionViewScrollPositionCenteredHorizontally = 1 << 4,
    UICollectionViewScrollPositionRight                = 1 << 5
};
typedef NS_ENUM(NSInteger, UICollectionViewReorderingCadence) {
    UICollectionViewReorderingCadenceImmediate,
    UICollectionViewReorderingCadenceFast,
    UICollectionViewReorderingCadenceSlow
} API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(tvos, watchos);
2.2、视图相关
  • 2.2.1、创立调集视图
#pragma mark ----- 创立调集视图 
//创立具有指定frame和layout的调集视图方针。
- (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout;
//依据给定解归档器中的数据创立调集视图方针。
- (nullable instancetype)initWithCoder:(NSCoder *)coder;
  • 2.2.2、创立单元格
#pragma mark -------- 创立单元格 
- (void)registerClass:(nullable Class)cellClass forCellWithReuseIdentifier:(NSString *)identifier;
- (void)registerNib:(nullable UINib *)nib forCellWithReuseIdentifier:(NSString *)identifier;
- (UICollectionViewCell *)dequeueReusableCellWithReuseIdentifier:(NSString *)identifier
       forIndexPath:(NSIndexPath *)indexPath;
- (UICollectionViewCell *)dequeueConfiguredReusableCellWithRegistration:(UICollectionViewCellRegistration*)registration 
   forIndexPath:(NSIndexPath*)indexPath item:(id)item;(iOS 14.0+)
  • 2.2.3、创立headers 和 footers
#pragma mark -----  创立headers 和 footers
NSString *const UICollectionElementKindSectionFooter;
NSString *const UICollectionElementKindSectionHeader;
- (void)registerClass:(nullable Class)viewClass forSupplementaryViewOfKind:(NSString *)elementKind withReuseIdentifier:(NSString *)identifier;
- (void)registerNib:(nullable UINib *)nib forSupplementaryViewOfKind:(NSString *)kind withReuseIdentifier:(NSString *)identifier;
- (UICollectionReusableView *)dequeueReusableSupplementaryViewOfKind:(NSString *)elementKind withReuseIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath;
- (UICollectionReusableView *)dequeueConfiguredReusableSupplementaryViewWithRegistration:(UICollectionViewSupplementaryRegistration*)registration forIndexPath:(NSIndexPath *)indexPath;(iOS 14.0+)
  • 2.2.4、装备布景视图
#pragma mark ----- 装备布景视图
//将主动调整巨细以盯梢调集视图的巨细,并放置在一切单元格和辅佐视图之后
@property (nonatomic, strong, nullable) UIView *backgroundView; 
2.3、数据相关
  • 2.3.1、供给调集视图数据
#pragma mark -----供给调集视图数据
@property (nonatomic, weak, nullable) id <UICollectionViewDataSource> dataSource;
#pragma mark ----- 预取调集视图单元格和数据
//一个布尔值,指示是否启用单元格和数据预取。
@property (nonatomic, getter=isPrefetchingEnabled) BOOL prefetchingEnabled;
//作为调集视图的预取数据源的方针,接纳行将到来的单元格数据需求的告知。
@property (nonatomic, weak, nullable) id<UICollectionViewDataSourcePrefetching> prefetchDataSource;
  • 2.3.2、 从头加载内容
//一个布尔值,指示调集视图是否包含删去占位符,
//还是作为处理删去的一部分从头排序其items。
//假如调集视图正在从头排序或具有删去占位符,则回来YES。
@property (nonatomic, readonly) BOOL hasUncommittedUpdates;
//更新您指定的索引途径上的项的数据,一起保存这些项的现有单元格。
//要更新现有(包括预取的)单元格的内容,而不运用新单元格替换它们,
//请运用此办法代替reloadItemsAtIndexPaths:。为了获得最佳功能,
//请挑选从头装备项,而不是从头加载项,除非清晰需求用新单元格替换现有单元格。
//单元格供给程序有必要为所供给的索引途径取出相同类型的单元格,
//而且有必要为给定的索引途径回来相同的现有单元格。由于此办法从头装备现有单元格,
//因而调集视图不会为每个退出行列的单元格调用prepareForReuse。
//假如您需求为索引途径回来不同类型的单元格,
//请运用reloadItemsAtIndexPaths:。
//假如单元格是自调整巨细的,则调集视图会在从头装备单元格后调整它们的巨细。
//默许情况下,调集视图将显现因从头装备而导致的任何巨细或布局更改。
//要从头装备没有动画的单元格,
//在调用这个办法时运用UIView的performWithoutAnimation:。或许,
//为了在设置特定特点时防止动画,能够在单元格装备逻辑中运用performWithoutAnimation:。
//假如您的调集视图运用UICollectionViewDataSource的自界说完结,
//请运用此办法。假如你的调集视图运用一个可变数据源,
//在NSDiffableDataSourceSnapshot上运用reconfigureItemsWithIdentifiers:。
//iOS15.0+
- (void)reconfigureItemsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths;
// 从头加载调集视图的一切数据。 
- (void)reloadData; 
// 从头加载调集视图的指定section中的数据。 
- (void)reloadSections:(NSIndexSet *)sections;
// 从头加载items索引途径
- (void)reloadItemsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths;
2.4、交互相关
  • 2.4.1、办理调集视图交互
#pragma mark -----办理调集视图交互
@property (nonatomic, weak, nullable) id <UICollectionViewDelegate> delegate;
#pragma mark -----办理拖动交互 
// 办理从调集视图拖动项目的署理方针。 
@property (nonatomic, weak, nullable) id <UICollectionViewDragDelegate> dragDelegate;
//一个布尔值,指示项是否已从调集视图中移除而且没有被删去。
@property (nonatomic, readonly) BOOL hasActiveDrag;
//一个布尔值,指示调集视图是否支撑拖动内容。
@property (nonatomic) BOOL dragInteractionEnabled;
#pragma mark -----办理drop交互  
// 用于办理将项目拖放到调集视图中的托付方针。 
@property (nonatomic, weak, nullable) id <UICollectionViewDropDelegate> dropDelegate;
//一个布尔值,指示调集视图当时是否正在盯梢删去会话。
@property (nonatomic, readonly) BOOL hasActiveDrop;
//指示在拖放进程中从头组织调集视图项的速度的常量。
@property (nonatomic)UICollectionViewReorderingCadence reorderingCadence;
  • 2.4.2、挑选单元格
#pragma mark ----- 挑选单元格
// 回来nil或选定索引途径的数组 。
@property (nonatomic, readonly, nullable) NSArray<NSIndexPath *> 
   *indexPathsForSelectedItems;
//挑选指定索引途径处的item,并可挑选将其翻滚到视图中。
- (void)selectItemAtIndexPath:(nullable NSIndexPath *)indexPath
 animated:(BOOL)animated scrollPosition:(UICollectionViewScrollPosition)scrollPosition;
//撤销挑选指定索引处的item。 
- (void)deselectItemAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated;
//这些特点控制是否能够挑选项目,假如能够,是否能够一起挑选多个项目。
// 一个布尔值,指示用户是否能够在调集视图中挑选item。 
//默许值是YES
@property (nonatomic) BOOL allowsSelection; 
 //一个布尔值,用于确认用户是否能够在调集视图中挑选多个item。 
//默许值是NO
@property (nonatomic) BOOL allowsMultipleSelection;
//一个布尔值,用于确认用户是否能够在调集视图处于修正形式时挑选单元格。
//iOS14.0+
@property (nonatomic) BOOL allowsSelectionDuringEditing;
//一个布尔值,控制用户是否能够在修正形式下一起挑选多个单元格。
//默许值是NO. (iOS14.0+)
@property (nonatomic) BOOL allowsMultipleSelectionDuringEditing; 
//一个布尔值,当焦点移动到单元格时触发主动挑选。iOS14.0+
@property (nonatomic) BOOL selectionFollowsFocus;
//将调集视图置于修正形式。iOS14.0+
@property (nonatomic, getter=isEditing) BOOL editing;
  • 2.4.3、刺进、移动和删去items
#pragma mark -----刺进、移动和删去items
//在指定索引处刺进新items。
- (void)insertItemsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths;
//删去指定索引途径上的items。
- (void)deleteItemsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths;
//将调集视图中的items从一个方位移动到另一个方位。
- (void)moveItemAtIndexPath:(NSIndexPath *)indexPath 
    toIndexPath:(NSIndexPath *)newIndexPath;
  • 2.4.4、刺进、移动和删去section
#pragma mark -----  刺进、移动和删去section
// 在指定索引处刺进新sections
- (void)insertSections:(NSIndexSet *)sections;
//删去指定索引途径上的sections
- (void)deleteSections:(NSIndexSet *)sections;
// 在调集视图中将section从一个方位移动到另一个方位。 
- (void)moveSection:(NSInteger)section toSection:(NSInteger)newSection;
  • 2.4.5、将item翻滚到视图中
#pragma mark ----- 将item翻滚到视图中
//翻滚调集视图内容,直到指定项可见停止。
- (void)scrollToItemAtIndexPath:(NSIndexPath *)indexPath 
  atScrollPosition:(UICollectionViewScrollPosition)scrollPosition 
        animated:(BOOL)animated;
  • 2.4.6、对调集视图进行多次更改
#pragma mark -----对调集视图进行多次更改
//将多个刺进、删去、从头加载和移动操作作为一个组进行动画化。
//答应多个刺进/删去/加载/移动调用一起动画。可嵌套的。
- (void)performBatchUpdates:
      (void (NS_NOESCAPE ^ _Nullable)(void))updates 
    completion:(void (^ _Nullable)(BOOL finished))completion; 
  • 2.4.7、 获取调集视图当时状况的信息
// 调集视图显现的section 个数。 
@property (nonatomic, readonly) NSInteger numberOfSections;
// 获取指定section中的item数。 
- (NSInteger)numberOfItemsInSection:(NSInteger)section;
// 调集视图当时显现的可见单元格的数组。 
@property (nonatomic, readonly) NSArray<UICollectionViewCell *> 
   *visibleCells;
  • 2.4.8、交互式地从头排序项目
//在指定的索引途径上发动item的交互移动。
//假如从头排序被阻挠,则回来NO,不然回来YES
//当您期望开端将项目从当时方位交互式移动到同一调集视图中的新方位时,调用此办法。
//当运用手势辨认器盯梢项目的移动时,请在手势辨认进程开端时从处理程序办法调用此办法。
//当与item的交互完毕时,您有必要调用endinteractivemomovement
//或cancelinteractivemomovement办法来告知调集视图这个事实。
//调用此办法时,调集视图将咨询其托付以确保能够移动项。
//假如数据源不支撑该项的移动,则此办法回来NO。
- (BOOL)beginInteractiveMovementForItemAtIndexPath:(NSIndexPath *)indexPath; 
//更新item在调集视图边界内的方位。
//以交互办法移动item时,请运用此办法为调集视图供给item的新方位。
//当运用手势辨认器盯梢用户与item的交互时,每次手势辨认器陈述方位更改时都调用此办法。
//调集视图运用新点来确认item目是否需求从头定位以及当时布局是否需求更新。
//对于每个方位更改,调集视图都会将更改陈述给其托付的
//collectionView:targetIndexPathForMoveFromItemAtIndexPath:toPProposedIndexPath:办法
- (void)updateInteractiveMovementTargetPosition:(CGPoint)targetPosition;
//完毕交互式移动盯梢,并将方针项目移动到新方位。
//在成功完结项目的移动盯梢时调用此办法。
//例如,当运用手势辨认器盯梢用户交互时,在手势成功完结时调用此办法。
//调用此办法让调集视图知道完毕盯梢并将项目永久移动到其新方位。
//调集视图经过调用其数据源的
//collectionView:moveItemAtIndexPath:toIndexPath:办法来进行呼应,
//以确保数据结构得到更新。
- (void)endInteractiveMovement;
//完毕交互式移动盯梢并将方针项目回来到其原始方位。
//调用此办法可撤销移动盯梢并将项目回来到其原始方位。
//例如,当运用手势辨认器盯梢交互时,在手势被撤销时调用此办法。
//调用此办法让调集视图知道完毕盯梢进程并将项目回来到其原始方位。
- (void)cancelInteractiveMovement;
//总结:要开端交互式从头定位项目,请调用调集视图的
//beginInteractiveMovementForItemAtIndexPath:办法。当手势辨认器
//盯梢接触事情时,请调用updateInteractiveMovementTargetPosition:办法
//来陈述接触方位的变化。完结手势盯梢后,
//调用endInteractiveMovement或cancelInteractiveMovements
//办法来完毕交互并更新调集视图。
2.5、布局相关
  • 2.5.1、改动布局
//用于组织搜集视图items的布局。
@property (nonatomic, strong)UICollectionViewLayout *collectionViewLayout;
//更改调集视图的布局,并可挑选将更改动画化。
//从一种布局过渡到另一种布局
//此办法无需用户进一步交互即可更改布局。
//假如挑选对布局更改进行动画处理,则动画时刻和参数由调集视图控制。
- (void)setCollectionViewLayout:(UICollectionViewLayout *)layout
      animated:(BOOL)animated;
//更改调集视图的布局,并在动画完结时告知您。
- (void)setCollectionViewLayout:(UICollectionViewLayout *)layout 
       animated:(BOOL)animated 
         completion:(void (^ __nullable)(BOOL finished))completion;
//运用交互式过渡作用更改调集视图的当时布局。
//当您想运用中心转化更改调集视图的布局时,请调用此办法。
//当您调用此办法时,调集视图会悄悄地将回来的转化布局方针作为其当时布局方针。
//您有责任设置手势辨认器或其他接触事情处理代码来盯梢转化进展。
//随着进展的更改,请更新转化布局方针的transitionProgress特点并使布局无效。
//使其布局无效会导致转化布局方针依据新的进展值更新项目的方位。
//当事情处理代码确认用户已完结向新布局的转化时,
//请调用finishInteractiveTransition办法。
//假如您的代码确认用户现已撤销了转化,
//请调用cancelInteractiveTransition办法来恢复更改。
//调用这两种办法中的任何一种都会从调集视图中删去转化布局方针,
//并设置相应的方针布局方针。
//默许情况下,此办法回来UICollectionViewTransitionLayout类的一个实例。
//假如期望它回来自界说转化方针,请完结调集视图托付的
//collectionView:transitionLayoutForOldLayout:newLayout:办法,
//并运用该办法回来自界说方针。
- (UICollectionViewTransitionLayout *)startInteractiveTransitionToCollectionViewLayout:(UICollectionViewLayout *)layout 
   completion:(nullable UICollectionViewLayoutInteractiveTransitionCompletion)completion;
//告知调集视图经过设置方针布局来完结交互式转化。在调用
//startInteractiveTransitionToCollectionViewLayout:completion:办法之后,
//在您经过手势辨认器或其他事情处理代码确认用户想要过渡到新布局之后,调用此办法。
//此办法从调集视图中删去中心转化布局方针,并设置预期的方针布局方针。
//然后,它履行终究的动画,
//将调集视图的项从当时方位移到新装置的布局方针指定的方位。
//调用此办法后,还能够删去为办理转化的交互部分而设置的手势辨认器或事情处理代码。 
- (void)finishInteractiveTransition;
//告知调集视图撤销交互式过渡并回来到其原始布局方针。在调用
//startInteractiveTransitionToCollectionViewLayout:completion:办法之后,
//以及经过手势辨认器或其他事情处理代码确认用户要恢复到调集视图的原始布局之后,
//调用此办法。此办法从调集视图中删去中心过渡布局方针,并从头设置原始布局方针。
//然后,它履行任何终究动画,
//以将调集视图的项目从其当时方位获取到原始布局方针指定的方位。
//调用此办法后,还能够删去为办理转化的交互部分而装置的手势辨认器或事情处理代码。
- (void)cancelInteractiveTransition;
//在调集视图的交互式转化完毕时调用的完结块。
typedef void (^UICollectionViewLayoutInteractiveTransitionCompletion)(BOOL completed, BOOL finished);
  • 2.5.2、获取布局信息
//获取坐落指定索引途径处的item的布局信息。
- (nullable UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath;
//获取指定弥补视图的布局信息。
- (nullable UICollectionViewLayoutAttributes *)layoutAttributesForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath;
2.6、定位调集视图中的项和视图
//获取调集视图中指定点处item的索引途径。
//此办法依靠于相关布局方针供给的布局信息来确认哪个item包含该点。
- (nullable NSIndexPath *)indexPathForItemAtPoint:(CGPoint)point;
//调集视图中可见items的数组。
@property (nonatomic, readonly) NSArray<NSIndexPath *> 
      *indexPathsForVisibleItems;
//获取指定单元格的索引途径。
- (nullable NSIndexPath *)indexPathForCell:(UICollectionViewCell *)cell;
//获取指定索引途径处的单元格方针。
- (nullable UICollectionViewCell *)cellForItemAtIndexPath:(NSIndexPath *)indexPath;
//获取指定类型的可见弥补视图的数组。
- (NSArray<UICollectionReusableView *> *)visibleSupplementaryViewsOfKind:(NSString *)elementKind;
//获取指定类型的一切可见弥补视图的索引途径。
- (NSArray<NSIndexPath *> *)indexPathsForVisibleSupplementaryElementsOfKind:(NSString *)elementKind;
//获取指定索引途径上的弥补视图。
- (nullable UICollectionReusableView *)supplementaryViewForElementKind:(NSString *)elementKind 
        atIndexPath:(NSIndexPath *)indexPath;
2.7、办理上下文菜单
//调集视图的上下文菜单交互。
@property (nonatomic, readonly, nullable) UIContextMenuInteraction *contextMenuInteraction;
#pragma mark -----调整自调整巨细的单元格
//调集视图用于使自调整巨细单元格的巨细无效的形式。
//iOS16.0+
@property(nonatomic) UICollectionViewSelfSizingInvalidation selfSizingInvalidation;
2.8、Working with focus iOS15.0+
#pragma mark ----- Working with focus  iOS15.0+-----------
// 一个布尔值,用于确认调集视图是否答应其单元格成为焦点。 
//假如你完结了collectionView:canFocusItemAtIndexPath:,
//它的回来值优先于这个特点的值。
//体系依据渠道和调集视图的其他特点确认此特点的默许值。
@property(nonatomic) BOOL allowsFocus;
//一个布尔值,用于确认调集视图是否答应其单元格在修正形式下成为焦点。
//假如你完结了collectionView:canFocusItemAtIndexPath:,
//它的回来值优先于这个特点的值。
//体系依据渠道和调集视图的其他特点确认此特点的默许值。
@property(nonatomic) BOOL allowsFocusDuringEditing;
//一个布尔值,当焦点移动到单元格时触发主动挑选。
//体系依据渠道和调集视图的其他特点确认此特点的默许值。
@property(nonatomic) BOOL selectionFollowsFocus;
//一个布尔值,指示调集视图是否主动将焦点分配给终究聚集索引途径上的item。
//默许为NO。假如是,当聚集于调集视图时,终究聚集的索引途径将主动聚集。
//假如调集视图从未聚集过,则运用首选聚集索引途径。iOS9.0+
@property (nonatomic) BOOL remembersLastFocusedIndexPath; 
@end
2.9、其他
UIKIT_EXTERN API_AVAILABLE(ios(14.0),tvos(14.0))
@interface UICollectionViewCellRegistration : NSObject
+ (instancetype)registrationWithCellClass:(Class)cellClass configurationHandler:(UICollectionViewCellRegistrationConfigurationHandler)configurationHandler;
+ (instancetype)registrationWithCellNib:(UINib*)cellNib configurationHandler:(UICollectionViewCellRegistrationConfigurationHandler)configurationHandler;
@property(nonatomic,readonly,nullable) Class cellClass;
@property(nonatomic,readonly,nullable) UINib *cellNib;
@property(nonatomic,readonly) UICollectionViewCellRegistrationConfigurationHandler configurationHandler;
@end
UIKIT_EXTERN API_AVAILABLE(ios(14.0),tvos(14.0))
@interface UICollectionViewSupplementaryRegistration : NSObject
+ (instancetype)registrationWithSupplementaryClass:(Class)supplementaryClass elementKind:(NSString*)elementKind  configurationHandler:(UICollectionViewSupplementaryRegistrationConfigurationHandler)configurationHandler;
+ (instancetype)registrationWithSupplementaryNib:(UINib*)supplementaryNib elementKind:(NSString*)elementKind configurationHandler:(UICollectionViewSupplementaryRegistrationConfigurationHandler)configurationHandler;
@property(nonatomic,readonly,nullable) Class supplementaryClass;
@property(nonatomic,readonly,nullable) UINib *supplementaryNib;
@property(nonatomic,readonly) NSString *elementKind;
@property(nonatomic,readonly) UICollectionViewSupplementaryRegistrationConfigurationHandler configurationHandler;
@end

三、UICollectionViewDataSourcePrefetching

  • 一种协议,为调集视图供给数据需求的预先警告,答应触发异步数据加载操作。

在调用 collectionView:cellForItemAtIndexPath: 数据源办法之前,将预取数据源方针与调集视图的数据源结合运用,开端加载单元格的数据。

依照以下进程将预取数据源添加到调集视图:
  • 1、创立调集视图及其数据源。
  • 2、创立一个选用UICollectionViewDataSourcePrefetching 协议的方针,并将其分配给调集视图上的prefetchDataSource 特点。
  • 3、在collectionView:prefetchItemsAtIndexPaths: 的完结中,发动指定索引途径上单元格所需的数据的异步加载。
  • 4、 在collectionView:cellForItemAtIndexPath: 数据源办法的完结中,运用预取的数据预备要显现的单元格。
  • 5、当调集视图告知您在collectionView:cancelPrefetchingForItemsAtIndexPaths: 办法中不再需求数据时,撤销挂起的数据加载操作。

请注意: 不用为调集视图中的每个单元格调用预取办法。有关加载数据的主张办法的详细信息,请参阅Load data asynchronously(异步加载数据)。

Load data asynchronously(异步加载数据)

不一定要为调集视图中的每个单元格都调用不一定要为调集视图中的每个单元格都调用collectionView:prefetchItemsAtIndexPaths: 办法。因而,你对collectionView:cellForItemAtIndexPath: 的完结有必要能够处理以下潜在的情况:

  • 数据现已经过预取恳求加载完结, 并预备好显现。
  • 当时正在预取数据,但还不可用。
  • 现在没有恳求数据。

处理一切这些情况的一种办法是运用NSOperation来加载每一行的数据。您能够创立NSOperation方针并将其存储在预取办法中。然后,数据源办法能够检索操作和成果,或许在不存在的情况下创立它。有关如何运用异步编程模型完结所需行为的详细信息,请参阅并发编程攻略Concurrency Programming Guide。

@protocol UICollectionViewDataSourcePrefetching <NSObject>
@required
//告知预取数据源方针开端为供给的索引途径上的单元格预备数据。
//调集视图在用户翻滚时调用此办法,为不久的将来或许显现的单元格供给索引途径。
//此办法的完结负责发动任何贵重的数据加载进程。数据加载有必要异步履行,
//而且成果可用于调集视图数据源上的collectionView:cellForItemAtIndexPath:办法。
//调集视图不会为它当即需求的单元格调用此办法,因而代码不能依靠于此办法来加载数据。
//所供给的索引途径的次序表明优先级。
//有关创立异步数据加载任务的更多信息,请参阅并发编程攻略。
//indexPaths依照与调集视图的几许间隔升序摆放
- (void)collectionView:(UICollectionView *)collectionView 
   prefetchItemsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths;
@optional
// 撤销先前触发的数据预取恳求。 
//当单元格翻滚出视图时,调集视图调用此办法来撤销预取恳求。这个办法的完结负责
//撤销之前调用collectionView:prefetchItemsAtIndexPaths:所主张的操作。
//有关撤销异步数据加载任务的详细信息,请拜见并发编程攻略。
- (void)collectionView:(UICollectionView *)collectionView 
  cancelPrefetchingForItemsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths;
@end

在调用 collectionView:cellForItemAtIndexPath: 数据源办法之前,能够将预取数据源方针与调集视图的数据源结合运用,开端加载单元格的数据。

四、UICollectionViewDataSource

4.1、有必要完结的办法:
//回来 每个区 的 item 个数  
//有必要完结此办法
- (NSInteger)collectionView:(UICollectionView *)collectionView 
       numberOfItemsInSection:(NSInteger)section;
//有必要从对-dequeueReusableCellWithReuseIdentifier:forIndexPath:的调用中
//检索回来的单元格,有必要完结此办法.
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView 
       cellForItemAtIndexPath:(NSIndexPath *)indexPath;
4.2、可选的办法:

4.2.1、获取视图的区数

//回来 UICollectionView 有多少个区
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView;

4.2.2、获取项目的视图:

//此办法的完结负责创立、装备和回来所恳求的恰当的弥补视图(Supplementary views)。
//为此,您能够调用调集视图的dequeueReusableSupplementaryViewOfKind:withReuseIdentifier:forIndexPath:办法,
//并传递与所需视图对应的信息。该办法总是回来一个有用的视图方针。
//收到视图后,您应该设置与要显现的数据对应的一切财产,
//履行任何其他所需的装备,并回来视图。
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView 
          viewForSupplementaryElementOfKind:(NSString *)kind 
                    atIndexPath:(NSIndexPath *)indexPath;

4.2.3、从头排序办法:

#pragma mark -----Reordering items (从头排序)
//问询数据源方针指定的项是否能够移动到调集视图中的另一个方位。
//运用此办法能够挑选性地答应或不答应在调集视图中移动项目。
//假如未完结此办法,但完结了collectionView:moveItemAtIndexPath:toIndexPath:办法,
//则调集视图答应对一切项进行从头排序。
- (BOOL)collectionView:(UICollectionView *)collectionView 
         canMoveItemAtIndexPath:(NSIndexPath *)indexPath;
// 告知数据源方针将指定项移动到新方位。
//有必要完结此办法才能支撑对调集视图中的项进行从头排序。
//假如不完结此办法,调集视图将疏忽任何从头排序项目的测验。
//当与项的交互完毕时,假如项的方位产生更改,则调集视图将调用此办法。
//运用此办法能够运用新的索引途径信息更新数据结构。 
- (void)collectionView:(UICollectionView *)collectionView 
    moveItemAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath*)destinationIndexPath;

4.2.4、装备索引的办法:

#pragma mark -----Configuring an index (装备索引)
//回来要在索引视图中显现的索引标题列表(例如[“a”、“B”、“C”…“Z”、“#”])
//运用此办法支撑快速翻滚调集视图的内容。
//回来的字符串显现在一个索引视图中,该索引视图可用于跳转到调集视图内容中的特定方位。
//假如完结这个办法,
//还有必要完结collectionView:indexPathForIndexTitle:atIndex:办法
//来指定与每个索引标题相关的调集视图项。
- (NSArray<NSString *> *)indexTitlesForCollectionView:(UICollectionView *)collectionView;
//回来与给定标题/索引相对应的索引途径。(例如“B”,1)
//回来一个带有单个索引的索引途径,以指示整个节,而不是特定项。
//运用此办法能够支撑快速翻滚保藏视图的内容。
//从indexTitlesForCollectionView:办法回来一组索引字符串后,
//调集视图会为每个字符串调用此办法,以获取调集视图项作为翻滚方针。
- (NSIndexPath *)collectionView:(UICollectionView *)collectionView  
      indexPathForIndexTitle:(NSString *)title atIndex:(NSInteger)index;

五、UICollectionViewDelegate

5.1、办理选定的单元格的办法:

// 问询delegate是否应挑选指定的item。 
//假如不完结此办法,则默许回来值为YES。 
- (BOOL)collectionView:(UICollectionView *)collectionView 
      shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath;
// 告知delegate已挑选指定索引途径中的item。 
- (void)collectionView:(UICollectionView *)collectionView 
       didSelectItemAtIndexPath:(NSIndexPath *)indexPath;
// 问询delegate是否应撤销挑选指定的item。 
- (BOOL)collectionView:(UICollectionView *)collectionView 
     shouldDeselectItemAtIndexPath:(NSIndexPath *)indexPath; 
// 告知delegate 指定途径上的item已被撤销挑选。 
- (void)collectionView:(UICollectionView *)collectionView 
     didDeselectItemAtIndexPath:(NSIndexPath *)indexPath;
#pragma mark ----- iOS 13+ 才能够运用以下办法
//问询delegate 用户是否能够在调集视图中运用两指平移手势挑选多个item。
//当体系辨认出双指平移手势时,它会在将修正设置为YES之前调用此办法。
//假如您从该办法回来YES,则用户能够运用两个手指平移手势挑选多个项目。
//用户能够在水平或笔直翻滚的调集视图上运用两指平移手势挑选多个项目,但不能一起翻滚。
//双向翻滚的调集视图无法辨认手势或调用此办法。
//假如不完结此办法,体系将运用allowsMultipleSelectionDuringEditing的值来确认用户是否能够运用平移手势挑选多个项目。
- (BOOL)collectionView:(UICollectionView *)collectionView 
  shouldBeginMultipleSelectionInteractionAtIndexPath:(NSIndexPath *)indexPath;
//当用户开端运用双指平移手势在调集视图中挑选多个项目时,告知delegate。
- (void)collectionView:(UICollectionView *)collectionView 
   didBeginMultipleSelectionInteractionAtIndexPath:(NSIndexPath *)indexPath;
//当用户停止运用双指平移手势挑选调集视图中的多个项目时,告知delegate。
//在用户将手指从设备上抬起后,调集视图会调用此办法。
- (void)collectionViewDidEndMultipleSelectionInteraction:(UICollectionView *)collectionView;

5.2、办理单元格高亮显现的办法:

//假如回来 NO,则单元格不会高亮显现,体系将绕过整个挑选进程。也就是说体系不调用,
//collectionView:shouldSelectItemAtIndexPath:或任何其他与挑选相关的办法。
//假如回来YES,高亮显现设置为YES,
//则调用collectionView:didHighlightItemAtIndexPath:,体系开端挑选进程。
//假如不完结此办法,则默许回来值为YES。
- (BOOL)collectionView:(UICollectionView *)collectionView 
    shouldHighlightItemAtIndexPath:(NSIndexPath *)indexPath;
//告知delegate 指定索引途径上的item已高亮显现。
- (void)collectionView:(UICollectionView *)collectionView 
     didHighlightItemAtIndexPath:(NSIndexPath *)indexPath;
//告知delegate 突出显现已从指定索引途径的item中删去。 
- (void)collectionView:(UICollectionView *)collectionView 
     didUnhighlightItemAtIndexPath:(NSIndexPath *)indexPath;

5.3、盯梢视图的添加和删去的办法:

//告知delegate指定的单元格将在调集视图中显现。
- (void)collectionView:(UICollectionView *)collectionView  
    willDisplayCell:(UICollectionViewCell *)cell 
          forItemAtIndexPath:(NSIndexPath *)indexPath;
//告知delegate指定的单元格已从调集视图中删去。
- (void)collectionView:(UICollectionView *)collectionView 
     didEndDisplayingCell:(UICollectionViewCell *)cell 
         forItemAtIndexPath:(NSIndexPath *)indexPath;
//告知delegate指定的弥补视图行将显现在调集视图中。
- (void)collectionView:(UICollectionView *)collectionView 
  willDisplaySupplementaryView:(UICollectionReusableView *)view 
      forElementKind:(NSString *)elementKind 
        atIndexPath:(NSIndexPath *)indexPath;
 //告知delegate指定的弥补视图已从调集视图中删去。
- (void)collectionView:(UICollectionView *)collectionView 
 didEndDisplayingSupplementaryView:(UICollectionReusableView *)view 
      forElementOfKind:(NSString *)elementKind 
           atIndexPath:(NSIndexPath *)indexPath;

5.4、处理布局更改的办法:

// 问询在指定布局之间移动时要运用的自界说转化布局。 
//假如你想回来一个自界说的UICollectionViewTransitionLayout方针供转化期间运用,就完结这个办法。
//转化布局方针答应您在从一个布局转化到下一个布局时自界说单元格和装修视图的行为。
//通常,在布局之间的转化会导致项目直接从当时方位动画到新方位。运用过渡布局方针,
//您能够让方针遵从非线性途径,运用不同的计时算法,或依据传入的接触事情移动。
//假如你的托付没有完结这个办法,调集视图会
//创立一个规范的UICollectionViewTransitionLayout方针,并运用该方针来办理转化。
- (UICollectionViewTransitionLayout *)collectionView:(UICollectionView *)collectionView 
    transitionLayoutForOldLayout:(UICollectionViewLayout *)fromLayout 
         newLayout:(UICollectionViewLayout *)toLayout;
//使托付有时机自界说内容偏移量,用于布局更改和动画更新。
//在布局更新期间,或在布局之间转化时,调集视图调用此办法,
//让您有时机更改主张的内容偏移量,以便在动画完毕时运用。
//假如布局或动画或许导致项目的定位办法不是最适合您的设计,则能够回来一个新值。
//该办法在布局方针的targetContentOffsetForProposedContentOffset:办法之后调用。
//在不期望子类化布局方针以修正内容偏移量的情况下完结此办法。
- (CGPoint)collectionView:(UICollectionView *)collectionView 
  targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset;
//向署理问询当移动item时要运用的索引途径。
// 在item的交互式移动进程中,调集视图会调用此办法,以检查是否要供给与主张的途径不同的索引途径。
//您能够运用此办法来防止用户将项目放置在无效方位。
//例如,您或许会阻挠用户删去特定部分中的项目。 iOS 15+ 才能够运用此办法
- (NSIndexPath *)collectionView:(UICollectionView *)collectionView 
targetIndexPathForMoveOfItemFromOriginalIndexPath:(NSIndexPath *)originalIndexPath 
        atCurrentIndexPath:(NSIndexPath *)currentIndexPath 
            toProposedIndexPath:(NSIndexPath *)proposedIndexPath;

5.5、办理上下文菜单的办法:

// 告知delegate上下文菜单何时呈现。 iOS 13.2+
// configuration 要显现的菜单的装备。 
- (void)collectionView:(UICollectionView *)collectionView 
willDisplayContextMenuWithConfiguration:(UIContextMenuConfiguration *)configuration 
    animator:(id<UIContextMenuInteractionAnimating>)animator;
// 告知delegate上下文菜单何时消失。 iOS 13.2+
- (void)collectionView:(UICollectionView *)collectionView 
willEndContextMenuInteractionWithConfiguration:(UIContextMenuConfiguration *)configuration 
       animator:(id<UIContextMenuInteractionAnimating>)animator;
 // 当用户经过点击预览触发提交时,告知delegate。 iOS 13.0+
- (void)collectionView:(UICollectionView *)collectionView 
willPerformPreviewActionForMenuWithConfiguration:(UIContextMenuConfiguration *)configuration 
     animator:(id<UIContextMenuInteractionCommitAnimating>)animator;
// 向delegate 恳求指定索引途径上的项的上下文菜单装备。 iOS 16.0+
- (UIContextMenuConfiguration *)collectionView:(UICollectionView *)collectionView 
  contextMenuConfigurationForItemsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths 
              point:(CGPoint)point;
// 当上下文菜单交互开端时,恳求delegate预览指定索引途径中的项。 iOS 16.0+     
- (UITargetedPreview *)collectionView:(UICollectionView *)collectionView 
  contextMenuConfiguration:(UIContextMenuConfiguration *)configuration 
     highlightPreviewForItemAtIndexPath:(NSIndexPath *)indexPath;
// 当上下文菜单交互完毕时,恳求delegate预览指定索引途径处的项。iOS 16.0+ 
- (UITargetedPreview *)collectionView:(UICollectionView *)collectionView 
   contextMenuConfiguration:(UIContextMenuConfiguration *)configuration 
     dismissalPreviewForItemAtIndexPath:(NSIndexPath *)indexPath;

5.6、焦点的办法:

//您能够运用此办法或单元格的canBecomeFocused办法
//来控制调集视图中的哪些项能够接纳焦点。
//焦点引擎首要调用单元格的canBecomeFocused办法,
//该办法的默许完结遵从调集视图和此托付办法。
//假如不完结此办法,则重视项的能力取决于调集视图的项是否可选。
//当项目是可挑选的,它们也能够被聚集,
//就像这个办法现已回来YES相同;不然,他们就得不到重视。
- (BOOL)collectionView:(UICollectionView *)collectionView 
canFocusItemAtIndexPath:(NSIndexPath *)indexPath;
//当焦点将要改动到一个调集视图时,调集视图有必要挑选它的哪个子视图应该接纳该焦点。
//假如调集视图的remembersLastFocusedIndexPath特点被设置为YES,
//则调集视图将回来上次聚集的单元格的索引途径。
//假如remembersLastFocusedIndexPath特点为NO,
//或许由于之前没有聚集单元格而没有保存索引途径,调集视图将调用此办法,
//以便您能够指定哪个单元格应该接纳焦点。
//假如不完结此办法,调集视图将回来恰当的单元格。
//这个办法的作用或许会在视图控制器转化期间或转化后当即被疏忽,
//比方表明免除或导航堆栈弹出。
//在这种情况下,视图控制器测验将焦点恢复到在转化之前被聚集的项上(例如,
//在视图控制器被呈现或推送之前),这能够优先于此办法的作用。
//要了解如安在视图控制器中控制或禁用此行为,
//请拜见restoresFocusAfterTransition。
//假如你子类化UICollectionView,
//你也能够经过重写preferredFocusEnvironments特点来完结相同的行为,
//该preferredFocusEnvironments特点由UIFocusEnvironment协议界说,
//并被一切视图选用。
- (NSIndexPath *)indexPathForPreferredFocusedViewInCollectionView:(UICollectionView *)collectionView;
// 问询delegate是否应该改动焦点。 
//在焦点产生改动之前,焦点引擎会问询一切受影响的视图是否应该产生这种改动。
//作为呼应,调集视图调用此办法,使您有时机答应或阻挠更改。
//回来此办法以阻挠不应该产生的更改。
//例如,您能够运用它来确保单元格之间的导航按特定次序进行。
//假如不完结此办法,则调集视图将假定回来值为YES。
//假如您对UICollectionView进行子类化,
//您也能够经过重写shouldUpdateFocusInContext:办法来完结相同的行为,
//该办法由UIFocusEnvironment协议界说,并被一切视图选用。
- (BOOL)collectionView:(UICollectionView *)collectionView 
shouldUpdateFocusInContext:(UICollectionViewFocusUpdateContext *)context;
//当焦点相关的更改产生时,调集视图会调用此办法。
//您能够运用此办法更新应用程序的状况信息,或对应用程序的视觉外观进行动画更改。
//假如您对UICollectionView进行子类化,
//您也能够经过重写didUpdateFocusInContext:withAnimationCoordinator:
//办法来完结相同的行为,该办法由UIFocusEnvironment协议界说,并被一切视图选用。
- (void)collectionView:(UICollectionView *)collectionView 
didUpdateFocusInContext:(UICollectionViewFocusUpdateContext *)context 
withAnimationCoordinator:(UIFocusAnimationCoordinator *)coordinator;
//问询署理是否将相应索引途径上的单元格的挑选和聚集行为相关起来。
//假如调集视图的selectionFollowsFocus特点为YES,
//而且您从此托付办法回来NO,则当用户挑选单元格时,焦点仍会移动到该单元格。
//但是,当焦点移动到该单元时,该单元格不会主动挑选。iOS 15.0+
- (BOOL)collectionView:(UICollectionView *)collectionView 
selectionFollowsFocusForItemAtIndexPath:(NSIndexPath *)indexPath;

5.7、items的修正的办法:

// 确认指定的item是否可修正。 iOS 14.0+ 
- (BOOL)collectionView:(UICollectionView *)collectionView 
canEditItemAtIndexPath:(NSIndexPath *)indexPath;

5.8、办理单元格的操作的办法:( iOS 16.0+ )

// 问询托付是否对指定索引途径上的单元格履行首要操作。 
//首要操作答应您区分不同的用户操作和挑选的更改(如焦点更改或其他直接挑选更改)。
//当一个人在不扩展现有挑选的情况下挑选单个单元格时,会产生首要操作。
//UIKit在collectionView:performPrimaryActionForItemAtIndexPath:之前调用此办法。
- (BOOL)collectionView:(UICollectionView *)collectionView 
canPerformPrimaryActionForItemAtIndexPath:(NSIndexPath *)indexPath;
// 告知托付在指定的索引途径下对单元格履行首要操作。 
//首要操作答应您区分不同的用户操作和挑选的更改(如焦点更改或其他直接挑选更改)。
//当一个人在不扩展现有挑选的情况下挑选单个单元格时,会产生首要操作。
//UIKit在collectionView:shouldSelectItemAtIndexPath:和
//collectionView:didSelectItemAtIndexMath:之后调用此办法,
//不管单元格挑选状况是否更改。运用collectionView:didSelectItemAtIndexPath:
//更新当时视图控制器的状况(如其按钮、标题等),
//并运用collectionView:performPrimaryActionForItemAtIndexMath:
//履行导航或显现另一个拆分视图列等操作。
//假如collectionView:shouldSelectItemAtIndexPath:
//回来YES以答应在indexPath处挑选单元格,则当体系调用此办法时,
//只有该单元格具有挑选权。
//假如collectionView:should SelectItemAtIndexPath:回来NO,
//则体系将保存调集视图中的现有单元格挑选。
//您能够运用此行为在不更改挑选的情况下对不可挑选的按钮样式单元格履行首要操作。
- (void)collectionView:(UICollectionView *)collectionView 
performPrimaryActionForItemAtIndexPath:(NSIndexPath *)indexPath;

5.9、处理场景过渡的办法:

// 回来答应单元扩展到新场景的场景激活装备。 iOS 15.0+ 
- (UIWindowSceneActivationConfiguration *)collectionView:(UICollectionView *)collectionView 
   sceneActivationConfigurationForItemAtIndexPath:(NSIndexPath *)indexPath 
              point:(CGPoint)point;

5.10、控制绷簧加载行为

//确认是否为指定项目显现绷簧加载交互作用。
//假如不完结此办法,则调集视图将假定回来值为YES。
- (BOOL)collectionView:(UICollectionView *)collectionView 
shouldSpringLoadItemAtIndexPath:(NSIndexPath *)indexPath 
    withContext:(id<UISpringLoadedInteractionContext>)context;