一、概述
UICollectionView是一个集合视图,是许多不同对象之间的协作。
集合视图从数据源对象获取数据,数据源对象存储在集合视图的dataSource属性中。对于数据源,可以使用UICollectionViewDiffableDataSource对象,它提供了简单有效地管理集合视图数据和用户界面更新所需的行为。或者,您可以通过采用UICollectionViewDataSource协议来创建自定义数据源对象。
集合视图是一种使用灵活多变的布局(layout)来显示有序数据项集的方式。集合视图最常见的用途是以类似网格的排列方式显示项目,但iOS中的集合视图不仅仅能够显示行和列。使用集合视图,视觉元素的精确布局可以通过子类化定义,并且可以动态更改,因此您可以实现网格、堆栈、圆形布局、动态更改布局或您可以想象的任何类型的布局。
二、Collection View 是由多个对象协作而成:
![](https://img.haomeiwen.com/i11711200/9417a16eb8cbd6f8.png)
-
顶层:容器(UICollectionView)与管理者(UICollectionViewController)
-
UICollectionView
对象定义集合视图内容的可见区域。继承UIScrollView,可以根据需要包含一个大的可滚动区域。可以通过layout布局对象接收的布局信息来表示数据。 -
UICollectionViewController
对象为集合视图提供视图控制器级别的管理支持。它的使用是可选的。
-
-
Data:
-
UICollectionViewDataSource 数据源对象,必须提供的对象
- 数据源对象是与集合视图相关联的最重要的对象,也是您必须提供的对象。数据源管理集合视图的内容,并创建显示该内容所需的视图。要实现数据源对象,必须创建一个符合UICollectionViewDataSource 协议 的对象。
-
UICollectionViewDelegate 委托对象,是可选的
- 集合视图委托对象允许您从集合视图中截取感兴趣的消息,并自定义视图的行为。例如,使用代理对象来跟踪集合视图中项目的选择和高亮显示。与数据源对象不同,委托对象是可选的。
-
-
UICollectionReusableView 集合视图中显示的所有视图必须是UICollectionReusableView类的实例,该类支持集合视图使用的回收机制。循环视图(而不是创建新视图)总体上提高了性能,尤其是在滚动期间。 集合视图中布置三种类型的视觉元素:
-
UICollectionViewCell 是用于主要数据项的特定类型的可重用视图。
- UICollectionViewListCell (iOS 14+)
-
Supplementary views : 补充视图,可以使用补充视图来实现给定部分或整个UICollectionView的header和页footer 视图。辅助视图是可选的,它们的使用和放置由布局对象定义。
-
Decoration views :装饰视图,是完全由布局对象(Layout)拥有的视觉装饰,与
数据源对象中的任何数据无关
。例如,布局对象可能使用装饰视图来实现自定义背景外观(每个section的背景外观)。
-
-
Layout:
-
UICollectionViewLayout (布局对象)
-
UICollectionViewLayout的子类作为布局对象,负责定义集合视图中单元格和可重用视图的位置、大小和视觉属性。
-
UICollectionViewFlowLayout 流布局
- UICollectionViewFlowLayout类是一个具体的布局对象,用于实现网格或其他基于行的布局。您可以按原样使用该类,也可以将其与流委托对象结合使用,这样可以动态自定义布局信息。
-
UICollectionViewCompositionalLayout 组合布局
- UICollectionViewLayout的子类,是集合视图布局的一种类型,可组合、灵活和快速的,通过将每个较小的组件组合或合成到一个完整的布局中,可以为内容构建任何类型的视觉排列。组合布局由一个或多个部分组成,这些部分将布局分解为不同的视觉分组。每个部分都由一组单独的项目组成,这些项目是您想要呈现的最小数据单元。一个组可以将其项目排列在水平行、垂直列或自定义排列中。
-
UICollectionViewTransitionLayout 一种特殊类型的布局对象,用于在集合视图中从一种布局更改为另一种布局时实现行为。
-
-
UICollectionViewLayoutAttributes(布局属性)
- 在布局过程中,布局对象会创建布局属性对象(UICollectionViewLayoutAttributes类的实例),告诉集合视图在何处以及如何显示单元格和可重用视图。
-
- 每当在集合视图中插入、删除或移动数据项时,布局对象都会接收UICollectionViewUpdateItem类的实例。您永远不需要自己创建此类的实例。
-
三、UICollectionView
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);
@interface UICollectionView : UIScrollView <UIDataSourceTranslating>
#pragma mark --------视图相关 ------------
#pragma mark -----创建集合视图
//创建具有指定frame和layout的集合视图对象。
- (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout;
//根据给定解归档器中的数据创建集合视图对象。
- (nullable instancetype)initWithCoder:(NSCoder *)coder;
#pragma mark -----创建单元格
- (void)registerClass:(nullable Class)cellClass forCellWithReuseIdentifier:(NSString *)identifier;
- (void)registerNib:(nullable UINib *)nib forCellWithReuseIdentifier:(NSString *)identifier;
- (__kindof UICollectionViewCell *)dequeueReusableCellWithReuseIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath;
//iOS 14.0+
- (__kindof UICollectionViewCell *)dequeueConfiguredReusableCellWithRegistration:(UICollectionViewCellRegistration*)registration forIndexPath:(NSIndexPath*)indexPath item:(id)item API_AVAILABLE(ios(14.0),tvos(14.0));
#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;
- (__kindof UICollectionReusableView *)dequeueReusableSupplementaryViewOfKind:(NSString *)elementKind withReuseIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath;
//iOS 14.0+
- (__kindof UICollectionReusableView *)dequeueConfiguredReusableSupplementaryViewWithRegistration:(UICollectionViewSupplementaryRegistration*)registration forIndexPath:(NSIndexPath *)indexPath;
#pragma mark -----配置背景视图
//将自动调整大小以跟踪集合视图的大小,并放置在所有单元格和辅助视图之后
@property (nonatomic, strong, nullable) UIView *backgroundView;
#pragma mark ---------数据相关 --------------
#pragma mark -----提供集合视图数据
@property (nonatomic, weak, nullable) id <UICollectionViewDataSource> dataSource;
#pragma mark ----- 预取集合视图单元格和数据
//一个布尔值,指示是否启用单元格和数据预取。
@property (nonatomic, getter=isPrefetchingEnabled) BOOL prefetchingEnabled;
//作为集合视图的预取数据源的对象,接收即将到来的单元格数据需求的通知。
@property (nonatomic, weak, nullable) id<UICollectionViewDataSourcePrefetching> prefetchDataSource;
#pragma mark -----------交互相关 --------------
#pragma mark -----管理集合视图交互
@property (nonatomic, weak, nullable) id <UICollectionViewDelegate> delegate;
#pragma mark -----管理拖动交互 iOS 11.0+
// 管理从集合视图拖动项目的代理对象。
@property (nonatomic, weak, nullable) id <UICollectionViewDragDelegate> dragDelegate;
//一个布尔值,指示项是否已从集合视图中移除并且尚未被删除。
@property (nonatomic, readonly) BOOL hasActiveDrag;
//一个布尔值,指示集合视图是否支持拖动内容。
@property (nonatomic) BOOL dragInteractionEnabled;
#pragma mark -----管理drop交互 iOS 11.0+
// 用于管理将项目拖放到集合视图中的委托对象。
@property (nonatomic, weak, nullable) id <UICollectionViewDropDelegate> dropDelegate;
//一个布尔值,指示集合视图当前是否正在跟踪删除会话。
@property (nonatomic, readonly) BOOL hasActiveDrop;
//指示在拖放过程中重新组织集合视图项的速度的常量。
@property (nonatomic) UICollectionViewReorderingCadence reorderingCadence;
#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;
#pragma mark -----插入、移动和删除items
//在指定索引处插入新items。
- (void)insertItemsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths;
//删除指定索引路径上的items。
- (void)deleteItemsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths;
//将集合视图中的items从一个位置移动到另一个位置。
- (void)moveItemAtIndexPath:(NSIndexPath *)indexPath toIndexPath:(NSIndexPath *)newIndexPath;
#pragma mark ----- 插入、移动和删除section
// 在指定索引处插入新sections
- (void)insertSections:(NSIndexSet *)sections;
//删除指定索引路径上的sections
- (void)deleteSections:(NSIndexSet *)sections;
// 在集合视图中将section从一个位置移动到另一个位置。
- (void)moveSection:(NSInteger)section toSection:(NSInteger)newSection;
#pragma mark ----- 将item滚动到视图中
//滚动集合视图内容,直到指定项可见为止。
- (void)scrollToItemAtIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UICollectionViewScrollPosition)scrollPosition animated:(BOOL)animated;
#pragma mark -----对集合视图进行多次更改
//将多个插入、删除、重新加载和移动操作作为一个组进行动画化。
//允许多个插入/删除/加载/移动调用同时动画。可嵌套的。
- (void)performBatchUpdates:(void (NS_NOESCAPE ^ _Nullable)(void))updates completion:(void (^ _Nullable)(BOOL finished))completion;
#pragma mark ----------布局相关 ----------------
#pragma mark -----改变布局
//用于组织收集视图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);
#pragma mark -----获取布局信息
//获取位于指定索引路径处的item的布局信息。
- (nullable UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath;
//获取指定补充视图的布局信息。
- (nullable UICollectionViewLayoutAttributes *)layoutAttributesForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath;
#pragma mark ----- 获取集合视图当前状态的信息
// 集合视图显示的section 个数。
@property (nonatomic, readonly) NSInteger numberOfSections;
// 获取指定section中的item数。
- (NSInteger)numberOfItemsInSection:(NSInteger)section;
// 集合视图当前显示的可见单元格的数组。
@property (nonatomic, readonly) NSArray<__kindof UICollectionViewCell *> *visibleCells;
#pragma mark ----- 定位集合视图中的项和视图
//获取集合视图中指定点处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;
#pragma mark -----------重新加载内容--------------
//一个布尔值,指示集合视图是否包含删除占位符,还是作为处理删除的一部分重新排序其items。
//如果集合视图正在重新排序或具有删除占位符,则返回YES。
//iOS11.0+
@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;
#pragma mark -----管理上下文菜单
//集合视图的上下文菜单交互。
@property (nonatomic, readonly, nullable) UIContextMenuInteraction *contextMenuInteraction;
#pragma mark -----调整自调整大小的单元格
//集合视图用于使自调整大小单元格的大小无效的模式。
//iOS16.0+
@property(nonatomic) UICollectionViewSelfSizingInvalidation selfSizingInvalidation;
#pragma mark -----交互式地重新排序项目
//在指定的索引路径上启动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
//方法来结束交互并更新集合视图。
#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
UICollectionViewDataSourcePrefetching
- 一种协议,为集合视图提供数据需求的预先警告,允许触发异步数据加载操作。
在调用collectionView:cellForItemAtIndexPath:数据源方法之前,将预取数据源对象与集合视图的数据源结合使用,开始加载单元格的数据。
按照以下步骤将预取数据源添加到集合视图:
- 1、创建集合视图及其数据源。
- 2、创建一个采用UICollectionViewDataSourcePrefetching
协议的对象,并将其分配给集合视图上的prefetchDataSource
属性。 - 3、在collectionView:prefetchItemsAtIndexPaths:
的实现中,启动指定索引路径上单元格所需的数据的异步加载。 - 4、 在collectionView:cellForItemAtIndexPath:
数据源方法的实现中,使用预取的数据准备要显示的单元格。 - 5、当集合视图通知您在collectionView:cancelPrefetchingForItemsAtIndexPaths:
方法中不再需要数据时,取消挂起的数据加载操作。
请注意
:
不必为集合视图中的每个单元格调用预取方法。有关加载数据的建议方法的详细信息,请参阅异步加载数据。
Load data asynchronously(异步加载数据)
不一定要为集合视图中的每个单元格都调用不一定要为集合视图中的每个单元格都调用collectionView:prefetchItemsAtIndexPaths:
方法。因此,你对collectionView:cellForItemAtIndexPath:
的实现必须能够处理以下潜在的情况:
- 数据已经通过预取请求加载完成, 并准备好显示。
- 当前正在预取数据,但还不可用。
- 目前尚未请求数据。
处理所有这些情况的一种方法是使用NSOperation来加载每一行的数据。您可以创建NSOperation对象并将其存储在预取方法中。然后,数据源方法可以检索操作和结果,或者在不存在的情况下创建它。有关如何使用异步编程模型实现所需行为的详细信息,请参阅并发编程指南Concurrency Programming Guide。
@protocol UICollectionViewDataSourcePrefetching <NSObject>
@required
// indexPaths are ordered ascending by geometric distance from the collection view
//告诉预取数据源对象开始为提供的索引路径上的单元格准备数据。
//集合视图在用户滚动时调用此方法,为不久的将来可能显示的单元格提供索引路径。
//此方法的实现负责启动任何昂贵的数据加载过程。数据加载必须异步执行,
//并且结果可用于集合视图数据源上的collectionView:cellForItemAtIndexPath:方法。
//集合视图不会为它立即需要的单元格调用此方法,因此代码不能依赖于此方法来加载数据。
//所提供的索引路径的顺序表示优先级。
//有关创建异步数据加载任务的更多信息,请参阅并发编程指南。
//indexPaths按照与集合视图的几何距离升序排列
- (void)collectionView:(UICollectionView *)collectionView prefetchItemsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths API_AVAILABLE(ios(10.0));
@optional
// indexPaths that previously were considered as candidates for pre-fetching, but were not actually used; may be a subset of the previous call to -collectionView:prefetchItemsAtIndexPaths:
// 取消先前触发的数据预取请求。
//当单元格滚动出视图时,集合视图调用此方法来取消预取请求。这个方法的实现负责
//取消之前调用collectionView:prefetchItemsAtIndexPaths:所发起的操作。
//有关取消异步数据加载任务的详细信息,请参见并发编程指南。
- (void)collectionView:(UICollectionView *)collectionView cancelPrefetchingForItemsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths API_AVAILABLE(ios(10.0));
@end
在调用collectionView:cellForItemAtIndexPath:数据源方法之前,可以将预取数据源对象与集合视图的数据源结合使用,开始加载单元格的数据。
UICollectionViewDragDelegate
@protocol UICollectionViewDragDelegate <NSObject>
@required
/* Provide items to begin a drag associated with a given indexPath.
* If an empty array is returned a drag session will not begin.
*/
- (NSArray<UIDragItem *> *)collectionView:(UICollectionView *)collectionView itemsForBeginningDragSession:(id<UIDragSession>)session atIndexPath:(NSIndexPath *)indexPath;
@optional
/* Called to request items to add to an existing drag session in response to the add item gesture.
* You can use the provided point (in the collection view's coordinate space) to do additional hit testing if desired.
* If not implemented, or if an empty array is returned, no items will be added to the drag and the gesture
* will be handled normally.
*/
- (NSArray<UIDragItem *> *)collectionView:(UICollectionView *)collectionView itemsForAddingToDragSession:(id<UIDragSession>)session atIndexPath:(NSIndexPath *)indexPath point:(CGPoint)point;
/* Allows customization of the preview used for the item being lifted from or cancelling back to the collection view.
* If not implemented or if nil is returned, the entire cell will be used for the preview.
*/
- (nullable UIDragPreviewParameters *)collectionView:(UICollectionView *)collectionView dragPreviewParametersForItemAtIndexPath:(NSIndexPath *)indexPath;
/* Called after the lift animation has completed to signal the start of a drag session.
* This call will always be balanced with a corresponding call to -collectionView:dragSessionDidEnd:
*/
- (void)collectionView:(UICollectionView *)collectionView dragSessionWillBegin:(id<UIDragSession>)session;
/* Called to signal the end of the drag session.
*/
- (void)collectionView:(UICollectionView *)collectionView dragSessionDidEnd:(id<UIDragSession>)session;
/* Controls whether move operations (see UICollectionViewDropProposal.operation) are allowed for the drag session.
* If not implemented this will default to YES.
*/
- (BOOL)collectionView:(UICollectionView *)collectionView dragSessionAllowsMoveOperation:(id<UIDragSession>)session;
/* Controls whether the drag session is restricted to the source application.
* If YES the current drag session will not be permitted to drop into another application.
* If not implemented this will default to NO.
*/
- (BOOL)collectionView:(UICollectionView *)collectionView dragSessionIsRestrictedToDraggingApplication:(id<UIDragSession>)session;
@end
UICollectionViewDropDelegate
API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(tvos, watchos)
@protocol UICollectionViewDropDelegate <NSObject>
@required
/* Called when the user initiates the drop.
* Use the dropCoordinator to specify how you wish to animate the dropSession's items into their final position as
* well as update the collection view's data source with data retrieved from the dropped items.
* If the supplied method does nothing, default drop animations will be supplied and the collection view will
* revert back to its initial pre-drop session state.
*/
- (void)collectionView:(UICollectionView *)collectionView performDropWithCoordinator:(id<UICollectionViewDropCoordinator>)coordinator;
@optional
/* If NO is returned no further delegate methods will be called for this drop session.
* If not implemented, a default value of YES is assumed.
*/
- (BOOL)collectionView:(UICollectionView *)collectionView canHandleDropSession:(id<UIDropSession>)session;
/* Called when the drop session begins tracking in the collection view's coordinate space.
*/
- (void)collectionView:(UICollectionView *)collectionView dropSessionDidEnter:(id<UIDropSession>)session;
/* Called frequently while the drop session being tracked inside the collection view's coordinate space.
* When the drop is at the end of a section, the destination index path passed will be for a item that does not yet exist (equal
* to the number of items in that section), where an inserted item would append to the end of the section.
* The destination index path may be nil in some circumstances (e.g. when dragging over empty space where there are no cells).
* Note that in some cases your proposal may not be allowed and the system will enforce a different proposal.
* You may perform your own hit testing via -[UIDropSession locationInView]
*/
- (UICollectionViewDropProposal *)collectionView:(UICollectionView *)collectionView dropSessionDidUpdate:(id<UIDropSession>)session withDestinationIndexPath:(nullable NSIndexPath *)destinationIndexPath;
/* Called when the drop session is no longer being tracked inside the collection view's coordinate space.
*/
- (void)collectionView:(UICollectionView *)collectionView dropSessionDidExit:(id<UIDropSession>)session;
/* Called when the drop session completed, regardless of outcome. Useful for performing any cleanup.
*/
- (void)collectionView:(UICollectionView *)collectionView dropSessionDidEnd:(id<UIDropSession>)session;
/* Allows customization of the preview used for the item being dropped.
* If not implemented or if nil is returned, the entire cell will be used for the preview.
*
* This will be called as needed when animating drops via -[UICollectionViewDropCoordinator dropItem:toItemAtIndexPath:]
* (to customize placeholder drops, please see UICollectionViewDropPlaceholder.previewParametersProvider)
*/
- (nullable UIDragPreviewParameters *)collectionView:(UICollectionView *)collectionView dropPreviewParametersForItemAtIndexPath:(NSIndexPath *)indexPath;
@end
UICollectionViewFocusUpdateContext
- 在集合视图中存储特定于焦点更新的信息的上下文对象。
当焦点发生变化时,集合视图委托接收带有相关信息的上下文对象。您的委托方法使用此对象中的信息来创建动画或执行与焦点更改相关的其他任务。
@interface UICollectionViewFocusUpdateContext : UIFocusUpdateContext
//先前具有焦点的集合视图单元格的索引路径。
@property (nonatomic, strong, readonly, nullable) NSIndexPath *previouslyFocusedIndexPath;
//正在接收焦点的集合视图单元格的索引路径。
@property (nonatomic, strong, readonly, nullable) NSIndexPath *nextFocusedIndexPath;
@end
UICollectionViewCellRegistration
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
UICollectionViewSupplementaryRegistration
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
四、UICollectionViewDataSource
必须实现的方法:
//返回 每个区 的 item 个数
//必须实现此方法
- (NSInteger)collectionView:(UICollectionView *)collectionView
numberOfItemsInSection:(NSInteger)section;
//必须从对-dequeueReusableCellWithReuseIdentifier:forIndexPath:的调用中
//检索返回的单元格,必须实现此方法.
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath;
可选的方法:
1、获取视图的区数
#pragma mark ----- Getting item and section metrics
//返回 UICollectionView 有多少个区
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView;
2、获取项目的视图:
#pragma mark -----Getting views for items
//此方法的实现负责创建、配置和返回所请求的适当的补充视图(Supplementary views)。
//为此,您可以调用集合视图的dequeueReusableSupplementaryViewOfKind:withReuseIdentifier:forIndexPath:方法,
//并传递与所需视图对应的信息。该方法总是返回一个有效的视图对象。
//收到视图后,您应该设置与要显示的数据对应的所有财产,
//执行任何其他所需的配置,并返回视图。
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView
viewForSupplementaryElementOfKind:(NSString *)kind
atIndexPath:(NSIndexPath *)indexPath;
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、配置索引的方法:
#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
1、管理选定的单元格的方法:
#pragma mark ----- Managing the selected cells
// 询问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;
//询问delegate 用户是否可以在集合视图中使用两指平移手势选择多个item。
//当系统识别出双指平移手势时,它会在将编辑设置为YES之前调用此方法。
//如果您从该方法返回YES,则用户可以使用两个手指平移手势选择多个项目。
//用户可以在水平或垂直滚动的集合视图上使用两指平移手势选择多个项目,但不能同时滚动。
//双向滚动的集合视图无法识别手势或调用此方法。
//如果不实现此方法,系统将使用allowsMultipleSelectionDuringEditing的值来确定用户是否可以使用平移手势选择多个项目。
//iOS 13+ 才可以使用此方法
- (BOOL)collectionView:(UICollectionView *)collectionView
shouldBeginMultipleSelectionInteractionAtIndexPath:(NSIndexPath *)indexPath;
//当用户开始使用双指平移手势在集合视图中选择多个项目时,告诉delegate。
//iOS 13+ 才可以使用此方法
- (void)collectionView:(UICollectionView *)collectionView
didBeginMultipleSelectionInteractionAtIndexPath:(NSIndexPath *)indexPath;
//当用户停止使用双指平移手势选择集合视图中的多个项目时,告诉delegate。
//在用户将手指从设备上抬起后,集合视图会调用此方法。
//iOS 13+ 才可以使用此方法
- (void)collectionViewDidEndMultipleSelectionInteraction:(UICollectionView *)collectionView;
2、管理单元格高亮显示的方法:
#pragma mark ----- Managing cell highlighting
- (BOOL)collectionView:(UICollectionView *)collectionView shouldHighlightItemAtIndexPath:(NSIndexPath *)indexPath;
- (void)collectionView:(UICollectionView *)collectionView didHighlightItemAtIndexPath:(NSIndexPath *)indexPath;
- (void)collectionView:(UICollectionView *)collectionView didUnhighlightItemAtIndexPath:(NSIndexPath *)indexPath;
3、跟踪视图的添加和删除的方法:
#pragma mark ----- 跟踪视图的添加和删除
//集合视图在将单元格添加到其内容之前调用此方法。
//使用此方法可以检测单元格添加,而不是监视单元格本身以查看它何时出现。
- (void)collectionView:(UICollectionView *)collectionView
willDisplayCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath;
//
- (void)collectionView:(UICollectionView *)collectionView
willDisplaySupplementaryView:(UICollectionReusableView *)view forElementKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath;
//
- (void)collectionView:(UICollectionView *)collectionView didEndDisplayingCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath;
//
- (void)collectionView:(UICollectionView *)collectionView
didEndDisplayingSupplementaryView:(UICollectionReusableView *)view
forElementOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath;
4、处理布局更改的方法:
#pragma mark ----- Handling layout changes 处理布局更改
// 询问在指定布局之间移动时要使用的自定义转换布局。
//如果你想返回一个自定义的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、管理上下文菜单的方法:
#pragma mark ----- Managing context menus 管理上下文菜单
// 通知delegate上下文菜单何时出现。
// configuration 要显示的菜单的配置。
- (void)collectionView:(UICollectionView *)collectionView
willDisplayContextMenuWithConfiguration:(UIContextMenuConfiguration *)configuration
animator:(id<UIContextMenuInteractionAnimating>)animator;
// 通知delegate上下文菜单何时消失。
// configuration 要显示的菜单的配置。
//iOS 13.2+
- (void)collectionView:(UICollectionView *)collectionView
willEndContextMenuInteractionWithConfiguration:(UIContextMenuConfiguration *)configuration
animator:(id<UIContextMenuInteractionAnimating>)animator;
6、焦点的方法:
#pragma mark -----Working with focus
//您可以使用此方法或单元格的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;
6、items的编辑的方法:
#pragma mark -----Editing items
// 确定指定的item是否可编辑。
// iOS 14.0+
- (BOOL)collectionView:(UICollectionView *)collectionView
canEditItemAtIndexPath:(NSIndexPath *)indexPath;
7、管理单元格的操作的方法:
#pragma mark -----Managing actions for cells 管理单元格的操作
// 询问委托是否对指定索引路径上的单元格执行主要操作。
//主要操作允许您区分不同的用户操作和选择的更改(如焦点更改或其他间接选择更改)。
//当一个人在不扩展现有选择的情况下选择单个单元格时,会发生主要操作。
//UIKit在collectionView:performPrimaryActionForItemAtIndexPath:之前调用此方法。
// iOS 16.0+
- (BOOL)collectionView:(UICollectionView *)collectionView
canPerformPrimaryActionForItemAtIndexPath:(NSIndexPath *)indexPath;
// 告诉委托在指定的索引路径下对单元格执行主要操作。
//主要操作允许您区分不同的用户操作和选择的更改(如焦点更改或其他间接选择更改)。
//当一个人在不扩展现有选择的情况下选择单个单元格时,会发生主要操作。
//UIKit在collectionView:shouldSelectItemAtIndexPath:和
//collectionView:didSelectItemAtIndexMath:之后调用此方法,
//无论单元格选择状态是否更改。使用collectionView:didSelectItemAtIndexPath:
//更新当前视图控制器的状态(如其按钮、标题等),
//并使用collectionView:performPrimaryActionForItemAtIndexMath:
//执行导航或显示另一个拆分视图列等操作。
//如果collectionView:shouldSelectItemAtIndexPath:
//返回YES以允许在indexPath处选择单元格,则当系统调用此方法时,
//只有该单元格具有选择权。
//如果collectionView:should SelectItemAtIndexPath:返回NO,
//则系统将保留集合视图中的现有单元格选择。
//您可以使用此行为在不更改选择的情况下对不可选择的按钮样式单元格执行主要操作。
// iOS 16.0+
- (void)collectionView:(UICollectionView *)collectionView
performPrimaryActionForItemAtIndexPath:(NSIndexPath *)indexPath;
8、处理场景过渡的方法:
#pragma mark -----Handling scene transitions 处理场景过渡
// 返回允许单元扩展到新场景的场景激活配置。
// iOS 15.0+
- (UIWindowSceneActivationConfiguration *)collectionView:(UICollectionView *)collectionView
sceneActivationConfigurationForItemAtIndexPath:(NSIndexPath *)indexPath
point:(CGPoint)point;
#pragma mark ----- 控制弹簧加载行为
//确定是否为指定项目显示弹簧加载交互效果。
//如果不实现此方法,则集合视图将假定返回值为YES。
// iOS 11.0+
- (BOOL)collectionView:(UICollectionView *)collectionView
shouldSpringLoadItemAtIndexPath:(NSIndexPath *)indexPath
withContext:(id<UISpringLoadedInteractionContext>)context;
网友评论