UICollectionView基础API笔记

 

UICollectionView系列API,属性含义笔记。在UICollectionView笔记1中我们了解了UICollectionView是什么,以及可以做什么;在UICollectionView笔记2中我们了解了UICollectionViewLayout相关内容。这一篇我们就UICollectionView相关API做一个整体的了解。

 

一、UICollectionView

  UICollectionView继承自UIScrollView,是一种新的数据展示方式。内置的UICollectionViewFlowLayout提供了多行多列的展示方式,UICollectionViewDataSouce提供了数据源协议,UICollectionViewDelegate提供了UI交互的先关协议,使用UICollectionView我们可以用很少的代码就可以实现很多复杂的效果,下面是相关API以及属性:

//直接初始化方法,需要提供一个Layout
- (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout NS_DESIGNATED_INITIALIZER;
//从nib文件直接初始化
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder NS_DESIGNATED_INITIALIZER;
//当前Layout
@property (nonatomic, strong) UICollectionViewLayout *collectionViewLayout;
//用户交互Delegate
@property (nonatomic, weak, nullable) id <UICollectionViewDelegate> delegate;
//UI的数据源DataSource
@property (nonatomic, weak, nullable) id <UICollectionViewDataSource> dataSource;

//iOS10新增加的Pre-Fetching预加载协议
@property (nonatomic, weak, nullable) id<UICollectionViewDataSourcePrefetching> prefetchDataSource NS_AVAILABLE_IOS(10_0);
//是否允许预加载
@property (nonatomic, getter=isPrefetchingEnabled) BOOL prefetchingEnabled NS_AVAILABLE_IOS(10_0);
//背景图片,自动根据collectionView的大小调整
@property (nonatomic, strong, nullable) UIView *backgroundView; 

//注册UICollectionViewCell,或其子类,并且提供一个复用标识符,在runtime的时候会初始化这个对象
- (void)registerClass:(nullable Class)cellClass forCellWithReuseIdentifier:(NSString *)identifier;
//通过nib文件注册复用cell
- (void)registerNib:(nullable UINib *)nib forCellWithReuseIdentifier:(NSString *)identifier;
//通过Class注册补充视图,并且指定补充视图的种类
- (void)registerClass:(nullable Class)viewClass forSupplementaryViewOfKind:(NSString *)elementKind withReuseIdentifier:(NSString *)identifier;
//通过nib文件注册补充视图
- (void)registerNib:(nullable UINib *)nib forSupplementaryViewOfKind:(NSString *)kind withReuseIdentifier:(NSString *)identifier;

//从复用队列通过指定Identifier获取复用cell
- (__kindof UICollectionViewCell *)dequeueReusableCellWithReuseIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath;
//从复用队列通过指定Identifier获取复用ReusableView 
- (__kindof UICollectionReusableView *)dequeueReusableSupplementaryViewOfKind:(NSString *)elementKind withReuseIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath;

//是否允许items选中,默认YES
@property (nonatomic) BOOL allowsSelection; // default is YES
//是否允许items多选,默认NO
@property (nonatomic) BOOL allowsMultipleSelection; // default is NO

//返回选中的index paths,返回nil或者NSArray
#if UIKIT_DEFINE_AS_PROPERTIES
@property (nonatomic, readonly, nullable) NSArray<NSIndexPath *> *indexPathsForSelectedItems; 
#else
- (nullable NSArray<NSIndexPath *> *)indexPathsForSelectedItems; 
#endif

//选中和解选indexPath对应item,可指定动画和UICollectionViewScrollPosition
- (void)selectItemAtIndexPath:(nullable NSIndexPath *)indexPath animated:(BOOL)animated scrollPosition:(UICollectionViewScrollPosition)scrollPosition;
- (void)deselectItemAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated;

//刷新数据
- (void)reloadData; 

//切换当前collectionView的layout
- (void)setCollectionViewLayout:(UICollectionViewLayout *)layout animated:(BOOL)animated; 
//切换当前collectionView的layout,配置完成之后的block(iOS7之后可用)
- (void)setCollectionViewLayout:(UICollectionViewLayout *)layout animated:(BOOL)animated completion:(void (^ __nullable)(BOOL finished))completion NS_AVAILABLE_IOS(7_0);
//改变当前collectionView的layout,使用interactive transition effect.
- (UICollectionViewTransitionLayout *)startInteractiveTransitionToCollectionViewLayout:(UICollectionViewLayout *)layout completion:(nullable UICollectionViewLayoutInteractiveTransitionCompletion)completion NS_AVAILABLE_IOS(7_0);
//layout切换过渡完成
- (void)finishInteractiveTransition NS_AVAILABLE_IOS(7_0);
//取消过渡切换layout
- (void)cancelInteractiveTransition NS_AVAILABLE_IOS(7_0);

//下面是UICollectionView的状态信息

//返回section的数量
#if UIKIT_DEFINE_AS_PROPERTIES
@property (nonatomic, readonly) NSInteger numberOfSections;
#else
- (NSInteger)numberOfSections;
#endif
//返回对应section中item的数量
- (NSInteger)numberOfItemsInSection:(NSInteger)section;
//返回对应indexPath的item的LayoutAttributes
- (nullable UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath;
//返回对应indexPath的ReuseView的LayoutAttributes
- (nullable UICollectionViewLayoutAttributes *)layoutAttributesForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath;
//返回对应point的indexPath
- (nullable NSIndexPath *)indexPathForItemAtPoint:(CGPoint)point;
//返回对应cell的indexPath
- (nullable NSIndexPath *)indexPathForCell:(UICollectionViewCell *)cell;
//返回对应indexPath的cell
- (nullable UICollectionViewCell *)cellForItemAtIndexPath:(NSIndexPath *)indexPath;

//返回collectionView当前可见的item数组和可见item的indexPath数组
#if UIKIT_DEFINE_AS_PROPERTIES
@property (nonatomic, readonly) NSArray<__kindof UICollectionViewCell *> *visibleCells;
@property (nonatomic, readonly) NSArray<NSIndexPath *> *indexPathsForVisibleItems;
#else
- (NSArray<__kindof UICollectionViewCell *> *)visibleCells;
- (NSArray<NSIndexPath *> *)indexPathsForVisibleItems;
#endif

//返回对应indexPath的ReuseView(iOS9之后可用)
- (nullable UICollectionReusableView *)supplementaryViewForElementKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(9_0);
//返回collectionView当前可见的ReuseView数组
- (NSArray<UICollectionReusableView *> *)visibleSupplementaryViewsOfKind:(NSString *)elementKind NS_AVAILABLE_IOS(9_0);
//返回collectionView当前可见ReuseView的indexPath数组
- (NSArray<NSIndexPath *> 
*)indexPathsForVisibleSupplementaryElementsOfKind:(NSString *)elementKind NS_AVAILABLE_IOS(9_0);

//下面是UICollectionView的交互相关信息

//滚动到指定的indexPath
- (void)scrollToItemAtIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UICollectionViewScrollPosition)scrollPosition animated:(BOOL)animated;

//插入一个section
- (void)insertSections:(NSIndexSet *)sections;
//删除一个section
- (void)deleteSections:(NSIndexSet *)sections;
//刷新一个section
- (void)reloadSections:(NSIndexSet *)sections;
//移动一个section到另外一个section
- (void)moveSection:(NSInteger)section toSection:(NSInteger)newSection;

//插入一个section
- (void)insertItemsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths;
//删除一个section
- (void)deleteItemsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths;
//刷新一个section
- (void)reloadItemsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths;
//移动一个indexPath的item到另一个indexPath的item
- (void)moveItemAtIndexPath:(NSIndexPath *)indexPath toIndexPath:(NSIndexPath *)newIndexPath;

//一次性操作插入,删除,刷新,移动操作
//Animates multiple insert, delete, reload, and move operations as a group
- (void)performBatchUpdates:(void (^ __nullable)(void))updates completion:(void (^ __nullable)(BOOL finished))completion; // allows multiple insert/delete/reload/move calls to be animated simultaneously. Nestable.

// 排序相关

//是否允许排序,默认YES(iOS9之后有效)
- (BOOL)beginInteractiveMovementForItemAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(9_0); 
//更新item的位置
- (void)updateInteractiveMovementTargetPosition:(CGPoint)targetPosition NS_AVAILABLE_IOS(9_0);
//移动item到新的position
- (void)endInteractiveMovement NS_AVAILABLE_IOS(9_0);
//回复item到原始的position
- (void)cancelInteractiveMovement NS_AVAILABLE_IOS(9_0);

//是否记住最后操作的indexPath,默认NO
@property (nonatomic) BOOL remembersLastFocusedIndexPath NS_AVAILABLE_IOS(9_0);

//UICollectionView 补充 的indexPath
@interface NSIndexPath (UICollectionViewAdditions)
//初始化indexPath
+ (instancetype)indexPathForItem:(NSInteger)item inSection:(NSInteger)section NS_AVAILABLE_IOS(6_0);
//返回IndexPath的item
@property (nonatomic, readonly) NSInteger item NS_AVAILABLE_IOS(6_0);
@end

//UICollectionViewDataSource数据源协议
@protocol UICollectionViewDataSource <NSObject>

@required
//配置UICollectionView的section对应item的数量
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section;

//配置UICollectionView的item,需要提前注册
- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath;

@optional
//配置UICollectionView的section数量
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView;

//配置UICollectionView的ReuseView,需要提前注册
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath;

//是否可以移动
- (BOOL)collectionView:(UICollectionView *)collectionView canMoveItemAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(9_0);
//移动indexPath的item到另一个indexPath
- (void)collectionView:(UICollectionView *)collectionView moveItemAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath*)destinationIndexPath NS_AVAILABLE_IOS(9_0);

@end

//UICollectionViewDelegate UI交互协议
@protocol UICollectionViewDelegate <UIScrollViewDelegate>

@optional
//是否允许高亮
- (BOOL)collectionView:(UICollectionView *)collectionView shouldHighlightItemAtIndexPath:(NSIndexPath *)indexPath;
//已经高亮
- (void)collectionView:(UICollectionView *)collectionView didHighlightItemAtIndexPath:(NSIndexPath *)indexPath;
//取消高亮
- (void)collectionView:(UICollectionView *)collectionView didUnhighlightItemAtIndexPath:(NSIndexPath *)indexPath;
//是否允许选中
- (BOOL)collectionView:(UICollectionView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath;
//是否允许解选
- (BOOL)collectionView:(UICollectionView *)collectionView shouldDeselectItemAtIndexPath:(NSIndexPath *)indexPath; // called when the user taps on an already-selected item in multi-select mode
//已经选中
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath;
//已经解选
- (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath;

//将要显示item(iOS8之后可用)
- (void)collectionView:(UICollectionView *)collectionView willDisplayCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(8_0);
//将要显示SupplementaryView(iOS8之后可用)
- (void)collectionView:(UICollectionView *)collectionView willDisplaySupplementaryView:(UICollectionReusableView *)view forElementKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(8_0);
//已经显示item
- (void)collectionView:(UICollectionView *)collectionView didEndDisplayingCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath;
//已经显示SupplementaryView
- (void)collectionView:(UICollectionView *)collectionView didEndDisplayingSupplementaryView:(UICollectionReusableView *)view forElementOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath;

//是否允许展示copy/paste Menu
- (BOOL)collectionView:(UICollectionView *)collectionView shouldShowMenuForItemAtIndexPath:(NSIndexPath *)indexPath;
//是否可以执行SEL
- (BOOL)collectionView:(UICollectionView *)collectionView canPerformAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(nullable id)sender;
//执行SEL
- (void)collectionView:(UICollectionView *)collectionView performAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(nullable id)sender;

@end

  

二、UICollectionViewCell

   UICollectionView为了优化性能,item和supplementView都采用复用队列的形式来返回,普通的补充视图直接就是UICollectionReusableView及其子类,item即UICollectionViewCell属于UICollectionReusableView的子类,下面是UICollectionReusableView的头文件声明:

//获取复用标识符reuseIdentifier
@property (nonatomic, readonly, copy, nullable) NSString *reuseIdentifier;

//从复用队列取到collectionView之前调用,子类在重写这个方法,完成返回之前的需要的配置
- (void)prepareForReuse;

//根据LayoutAttributes来布局当前View,在view被添加到collectionView上但是还没有被服用队列返回的时候调用
- (void)applyLayoutAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes;

// Override these methods to provide custom UI for specific layouts.
- (void)willTransitionFromLayout:(UICollectionViewLayout *)oldLayout toLayout:(UICollectionViewLayout *)newLayout;
- (void)didTransitionFromLayout:(UICollectionViewLayout *)oldLayout toLayout:(UICollectionViewLayout *)newLayout;

- (UICollectionViewLayoutAttributes *)preferredLayoutAttributesFittingAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes NS_AVAILABLE_IOS(8_0);

  下面是UICollectionViewCell的头文件声明:

//内容视图,子类图需要粘贴在contentView上面
@property (nonatomic, readonly) UIView *contentView;

//设置item的选中状态
@property (nonatomic, getter=isSelected) BOOL selected;
//设置item的高亮状态
@property (nonatomic, getter=isHighlighted) BOOL highlighted;

//背景图片
@property (nonatomic, strong, nullable) UIView *backgroundView;
//选中背景图片
@property (nonatomic, strong, nullable) UIView *selectedBackgroundView;

  

三、UICollectionViewController

  UICollectionViewContoller继承自UIViewController,默认实现了UICollectionViewDelegate和UICollectionViewDataSource,提供了一种简单使用UICollectionViewContoller的方式,类似于UITableViewController

//用指定的layout初始化UICollectionViewController
- (instancetype)initWithCollectionViewLayout:(UICollectionViewLayout *)layout NS_DESIGNATED_INITIALIZER;

//当前的collectionView
@property (nullable, nonatomic, strong) __kindof UICollectionView *collectionView;

//在viewWillAppear:时是否清除选中效果,默认YES
@property (nonatomic) BOOL clearsSelectionOnViewWillAppear;

//在导航过渡的时候是否使用layout,在push之前设置,之后设置无效
@property (nonatomic, assign) BOOL useLayoutToLayoutNavigationTransitions NS_AVAILABLE_IOS(7_0);

//当前的collectionViewLayout,只读属性
@property (nonatomic, readonly) UICollectionViewLayout *collectionViewLayout NS_AVAILABLE_IOS(7_0);

//是否允许排序,默认是YES
@property (nonatomic) BOOL installsStandardGestureForInteractiveMovement NS_AVAILABLE_IOS(9_0);

 

四、UICollectionViewFlowLayout

   UICollectionViewFlowLayout是系统自带的简单的网格布局,用来展示多行多列数据。可以通过下面属性的配置来控制全局item的大小

//设置item行之间的最小间隔
@property (nonatomic) CGFloat minimumLineSpacing;
//设置item之间的最小间隔
@property (nonatomic) CGFloat minimumInteritemSpacing;
//设置item的大小
@property (nonatomic) CGSize itemSize;
//设置item大小的近似值,默认是CGSizeZero(iOS8之后有效)
@property (nonatomic) CGSize estimatedItemSize NS_AVAILABLE_IOS(8_0); // defaults to CGSizeZero - setting a non-zero size enables cells that self-size via -preferredLayoutAttributesFittingAttributes:
//设置滚动方向
@property (nonatomic) UICollectionViewScrollDirection scrollDirection; // default is UICollectionViewScrollDirectionVertical
//设置头部引用视图的大小,对于垂直滚动时,宽不起作用,高度起作用;水平滚动相反
@property (nonatomic) CGSize headerReferenceSize;
////设置尾部引用视图的大小
@property (nonatomic) CGSize footerReferenceSize;
//设置section的上下左右留白
@property (nonatomic) UIEdgeInsets sectionInset;

//下面两个属性在iOS9之后可用,用来设置是否粘贴头部在屏幕的头部和尾部在屏幕的尾部
@property (nonatomic) BOOL sectionHeadersPinToVisibleBounds NS_AVAILABLE_IOS(9_0);
@property (nonatomic) BOOL sectionFootersPinToVisibleBounds NS_AVAILABLE_IOS(9_0);

  

  当然也可以细致的配置每一个item大小,这时需要实现UICollectionViewDelegateFlowLayout协议

//设置具体indexPath的item大小
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath;
//设置具体section的上下左右留白
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section;
//设置行最小间隔
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section;
//设置item间最小间隔
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section;
//设置头部引用视图的大小
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section;
//设置尾部引用视图的大小
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section;

  

五、UICollectionViewLayout

  UICollectionViewLayout是UICollectionView的精髓,是区别于UITableView的一个重要特征,UICollectionView通过 UICollectionViewLayout 返回的 UICollectionViewLayoutAttributes 来布局每一个item。子类通过重写UICollectionViewLayout中的方法可以实现各种各样的布局样式,也可以使用另外一套布局来更新当前布局样式,更可结合 UIDynamicBehavior 等UI动力学完成各种各样的酷炫效果,下面是UICollectionViewLayoutAttributes的头文件内容:

//设置item的frame
@property (nonatomic) CGRect frame;
//设置item的center
@property (nonatomic) CGPoint center;
//设置item的size
@property (nonatomic) CGSize size;
//设置item的transform3D
@property (nonatomic) CATransform3D transform3D;
//设置item的bounds
@property (nonatomic) CGRect bounds NS_AVAILABLE_IOS(7_0);
//设置item的transform
@property (nonatomic) CGAffineTransform transform NS_AVAILABLE_IOS(7_0);
//设置item的alpha
@property (nonatomic) CGFloat alpha;
//设置item的zIndex,默认是0和其他item在同一平面,设置小于0,在其他item下面
@property (nonatomic) NSInteger zIndex; // default is 0
//设置item的hidden状态,通常为NO
@property (nonatomic, getter=isHidden) BOOL hidden; 
//设置item的indexPath
@property (nonatomic, strong) NSIndexPath *indexPath;
//设置当前元素的类别,是个美剧变量 cell/supplementaryView/decorationView
@property (nonatomic, readonly) UICollectionElementCategory representedElementCategory;
//展示的元素类型,如果是cell 则为nil
@property (nonatomic, readonly, nullable) NSString *representedElementKind; // nil when representedElementCategory is UICollectionElementCategoryCell

//指定indexPath的cell的layoutAttributes
+ (instancetype)layoutAttributesForCellWithIndexPath:(NSIndexPath *)indexPath;
//指定indexPath的supplementaryView的layoutAttributes
+ (instancetype)layoutAttributesForSupplementaryViewOfKind:(NSString *)elementKind withIndexPath:(NSIndexPath *)indexPath;
//指定indexPath的decorationView的layoutAttributes
+ (instancetype)layoutAttributesForDecorationViewOfKind:(NSString *)decorationViewKind withIndexPath:(NSIndexPath *)indexPath;

  

  下面是UICollectionViewLayout相关的API:

//构造函数
- (instancetype)init NS_DESIGNATED_INITIALIZER;
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder NS_DESIGNATED_INITIALIZER;

//当前layout服务的collectionView对象
@property (nullable, nonatomic, readonly) UICollectionView *collectionView;

//验证当前layout,会触发collectionView的reloadData
- (void)invalidateLayout;
//验证当前layout,并且提供一个验证的上下文,也会触发collectionView的reloadData
- (void)invalidateLayoutWithContext:(UICollectionViewLayoutInvalidationContext *)context NS_AVAILABLE_IOS(7_0);

//注册decorationView用Class/nib
- (void)registerClass:(nullable Class)viewClass forDecorationViewOfKind:(NSString *)elementKind;
- (void)registerNib:(nullable UINib *)nib forDecorationViewOfKind:(NSString *)elementKind;

  

  自定义layout需要关注的API:

//自定义layoutAttributesClass和invalidationContextClass在需要的时候
#if UIKIT_DEFINE_AS_PROPERTIES
@property(class, nonatomic, readonly) Class layoutAttributesClass; // override this method to provide a custom class to be used when instantiating instances of UICollectionViewLayoutAttributes
@property(class, nonatomic, readonly) Class invalidationContextClass NS_AVAILABLE_IOS(7_0); // override this method to provide a custom class to be used for invalidation contexts
#else
+ (Class)layoutAttributesClass; // override this method to provide a custom class to be used when instantiating instances of UICollectionViewLayoutAttributes
+ (Class)invalidationContextClass NS_AVAILABLE_IOS(7_0); // override this method to provide a custom class to be used for invalidation contexts
#endif

//UICollectionView在第一次layout的时候会调用prepareLayout,并且在当前layout invalidated之后也会调用这个方法,子类需要重写此方法完成相关配置
- (void)prepareLayout;

//UICollectionView会调用下面四个方法完成相关的配置信息

//返回给定rect内的layoutAttributes数组
- (nullable NSArray<__kindof UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect; 
//返回给定indexPath的item的layoutAttributes
- (nullable UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath;
//返回给定indexPath的supplementaryView的layoutAttributes,如果有
- (nullable UICollectionViewLayoutAttributes *)layoutAttributesForSupplementaryViewOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath;
//返回给定indexPath的decorationView的layoutAttributes,如果有
- (nullable UICollectionViewLayoutAttributes *)layoutAttributesForDecorationViewOfKind:(NSString*)elementKind atIndexPath:(NSIndexPath *)indexPath;

//是否验证给定的bounds,会引起UICollectionView刷新layout
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds; 

//返回给定bounds的无效上下文
- (UICollectionViewLayoutInvalidationContext *)invalidationContextForBoundsChange:(CGRect)newBounds NS_AVAILABLE_IOS(7_0);

//是否验证layoutAttributes
- (BOOL)shouldInvalidateLayoutForPreferredLayoutAttributes:(UICollectionViewLayoutAttributes *)preferredAttributes withOriginalAttributes:(UICollectionViewLayoutAttributes *)originalAttributes NS_AVAILABLE_IOS(8_0);
- (UICollectionViewLayoutInvalidationContext *)invalidationContextForPreferredLayoutAttributes:(UICollectionViewLayoutAttributes *)preferredAttributes withOriginalAttributes:(UICollectionViewLayoutAttributes *)originalAttributes NS_AVAILABLE_IOS(8_0);

- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity; // return a point at which to rest after scrolling - for layouts that want snap-to-point scrolling behavior
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset NS_AVAILABLE_IOS(7_0); // a layout can return the content offset to be applied during transition or update animations

//返回collectionView的contentSize
#if UIKIT_DEFINE_AS_PROPERTIES
@property(nonatomic, readonly) CGSize collectionViewContentSize; // Subclasses must override this method and use it to return the width and height of the collection view’s content. These values represent the width and height of all the content, not just the content that is currently visible. The collection view uses this information to configure its own content size to facilitate scrolling.
#else
- (CGSize)collectionViewContentSize; // Subclasses must override this method and use it to return the width and height of the collection view’s content. These values represent the width and height of all the content, not just the content that is currently visible. The collection view uses this information to configure its own content size to facilitate scrolling.
#endif

  

  刷新layout需要关注的 API:

- (void)prepareForCollectionViewUpdates:(NSArray<UICollectionViewUpdateItem *> *)updateItems;
- (void)finalizeCollectionViewUpdates; // called inside an animation block after the update

- (void)prepareForAnimatedBoundsChange:(CGRect)oldBounds; // UICollectionView calls this when its bounds have changed inside an animation block before displaying cells in its new bounds
- (void)finalizeAnimatedBoundsChange; // also called inside the animation block

// UICollectionView calls this when prior the layout transition animation on the incoming and outgoing layout
- (void)prepareForTransitionToLayout:(UICollectionViewLayout *)newLayout NS_AVAILABLE_IOS(7_0);
- (void)prepareForTransitionFromLayout:(UICollectionViewLayout *)oldLayout NS_AVAILABLE_IOS(7_0);
- (void)finalizeLayoutTransition NS_AVAILABLE_IOS(7_0);  // called inside an animation block after the transition


// This set of methods is called when the collection view undergoes an animated transition such as a batch update block or an animated bounds change.
// For each element on screen before the invalidation, finalLayoutAttributesForDisappearingXXX will be called and an animation setup from what is on screen to those final attributes.
// For each element on screen after the invalidation, initialLayoutAttributesForAppearingXXX will be called and an animation setup from those initial attributes to what ends up on screen.
- (nullable UICollectionViewLayoutAttributes *)initialLayoutAttributesForAppearingItemAtIndexPath:(NSIndexPath *)itemIndexPath;
- (nullable UICollectionViewLayoutAttributes *)finalLayoutAttributesForDisappearingItemAtIndexPath:(NSIndexPath *)itemIndexPath;
- (nullable UICollectionViewLayoutAttributes *)initialLayoutAttributesForAppearingSupplementaryElementOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)elementIndexPath;
- (nullable UICollectionViewLayoutAttributes *)finalLayoutAttributesForDisappearingSupplementaryElementOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)elementIndexPath;
- (nullable UICollectionViewLayoutAttributes *)initialLayoutAttributesForAppearingDecorationElementOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)decorationIndexPath;
- (nullable UICollectionViewLayoutAttributes *)finalLayoutAttributesForDisappearingDecorationElementOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)decorationIndexPath;

// These methods are called by collection view during an update block.
// Return an array of index paths to indicate views that the layout is deleting or inserting in response to the update.
- (NSArray<NSIndexPath *> *)indexPathsToDeleteForSupplementaryViewOfKind:(NSString *)elementKind NS_AVAILABLE_IOS(7_0);
- (NSArray<NSIndexPath *> *)indexPathsToDeleteForDecorationViewOfKind:(NSString *)elementKind NS_AVAILABLE_IOS(7_0);
- (NSArray<NSIndexPath *> *)indexPathsToInsertForSupplementaryViewOfKind:(NSString *)elementKind NS_AVAILABLE_IOS(7_0);
- (NSArray<NSIndexPath *> *)indexPathsToInsertForDecorationViewOfKind:(NSString *)elementKind NS_AVAILABLE_IOS(7_0);

  

  排序需要关注的layout API:

- (NSIndexPath *)targetIndexPathForInteractivelyMovingItem:(NSIndexPath *)previousIndexPath withPosition:(CGPoint)position NS_AVAILABLE_IOS(9_0);
- (UICollectionViewLayoutAttributes *)layoutAttributesForInteractivelyMovingItemAtIndexPath:(NSIndexPath *)indexPath withTargetPosition:(CGPoint)position NS_AVAILABLE_IOS(9_0);

- (UICollectionViewLayoutInvalidationContext *)invalidationContextForInteractivelyMovingItems:(NSArray<NSIndexPath *> *)targetIndexPaths withTargetPosition:(CGPoint)targetPosition previousIndexPaths:(NSArray<NSIndexPath *> *)previousIndexPaths previousPosition:(CGPoint)previousPosition NS_AVAILABLE_IOS(9_0);
- (UICollectionViewLayoutInvalidationContext *)invalidationContextForEndingInteractiveMovementOfItemsToFinalIndexPaths:(NSArray<NSIndexPath *> *)indexPaths previousIndexPaths:(NSArray<NSIndexPath *> *)previousIndexPaths movementCancelled:(BOOL)movementCancelled NS_AVAILABLE_IOS(9_0);

  

六、UICollectionViewTransitionLayout

  UICollectionViewTransitionLayout继承自UICollectionViewLayout,用于切换当前的layout,提供过渡时期的layout

//UICollectionView过渡的进度值
@property (assign, nonatomic) CGFloat transitionProgress;
//当前UICollectionView的layout
@property (readonly, nonatomic) UICollectionViewLayout *currentLayout;
//切换之后的layout
@property (readonly, nonatomic) UICollectionViewLayout *nextLayout;

//初始化TransitionLayout对象
- (instancetype)initWithCurrentLayout:(UICollectionViewLayout *)currentLayout nextLayout:(UICollectionViewLayout *)newLayout NS_DESIGNATED_INITIALIZER;
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder NS_DESIGNATED_INITIALIZER;

- (instancetype)init NS_UNAVAILABLE;

//下面的方法用于储存过渡期LayoutAttributes的变化值
- (void)updateValue:(CGFloat)value forAnimatedKey:(NSString *)key;
- (CGFloat)valueForAnimatedKey:(NSString *)key;

  

posted on 2016-09-28 09:43  流浪_先生  阅读(4417)  评论(0编辑  收藏  举报

导航