UI的实现

UICollectionView 介绍

2020-07-27  本文已影响0人  其实也没有

简介

UICollectionView用于展示集合视图,布局更加灵活; UICollectionView 继承于 UIScrollView,UICollectionViewDelegate 协议继承于 UIScrollViewDelegate 协议。所以在使用 UICollectionView 的时候,可以直接使用 UIScrollView 的各个属性方法。

内置的UICollectionViewFlowLayout提供了多行多列的展示方式,UICollectionViewDataSouce提供了数据源协议,UICollectionViewDelegate提供了UI交互的先关协议,使用UICollectionView我们可以用很少的代码就可以实现很多复杂的效果

API介绍

UIScrollView相关

UIScrollViewDelegate 的方法:

UICollectionView相关

基础

UITableView的创建只需要设置frame即可使用 UICollectionView除了需要frame,还需要一个布局参数Layout;

UICollectionView包含三个部分,它们都是UIView的子类:

  • Cells 用于展示内容的主体,对于不同的cell可以指定不同尺寸和不同的内容
  • 追加视图(Supplementary Views) 如果你对UITableView比较熟悉的话,可以理解为每个Section的Header或者Footer,用来标记每个section的view
  • 装饰视图(Decoration Views) 这是每个section的背景,比如iBooks中的书架就是这个
//直接初始化方法,需要提供一个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);
//下面这些方法更加强大,我们可以对布局更改后的动画进行设置
//这个方法传入一个布局策略layout,系统会开始进行布局渲染,返回一个UICollectionViewTransitionLayout对象
//这个UICollectionViewTransitionLayout对象管理动画的相关属性,我们可以进行设置
- (UICollectionViewTransitionLayout *)startInteractiveTransitionToCollectionViewLayout:(UICollectionViewLayout *)layout completion:(nullable UICollectionViewLayoutInteractiveTransitionCompletion)completion NS_AVAILABLE_IOS(7_0);
//准备好动画设置后,我们需要调用下面的方法进行布局动画的展示,之后会调用上面方法的block回调
//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
  
UICollectionViewLayout

UICollectionViewLayout是UICollectionView的精髓, 通过它可以构建出各种各样的布局;

它负责了将各个cell、Supplementary View和Decoration Views进行组织,为它们设定各自的属性,包括但不限于:

  • 位置
  • 尺寸
  • 透明度
  • 层级关系
  • 形状
  • 等等等等…
  • Layout决定了UICollectionView是如何显示在界面上的。在展示之前,一般需要生成合适的UICollectionViewLayout子类对象,并将其赋予CollectionView的collectionViewLayout属性。
系统子类UICollectionViewFlowLayout
自定义UICollectionViewLayout
0000000000000000000000  - 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;

0000000000000000000000 -   下面是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;


0000000000000000000000 - 自定义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


0000000000000000000000 -  刷新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);

0000000000000000000000 - 排序需要关注的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);
UICollectionViewDataSouce

提供了数据源协议

  • section的数量 -numberOfSectionsInCollection:
  • 某个section里有多少个item -collectionView:numberOfItemsInSection:
  • 对于某个位置应该显示什么样的cell -collectionView:cellForItemAtIndexPath:
@required
/* 设置容器视图各个组都有多少个Cell方块 */
- (NSInteger)collectionView:(UICollectionView *)collectionView 
     numberOfItemsInSection:(NSInteger)section;
/* 设置Cell方块视图,类似于UITableViewCell的设置 */
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView 
                  cellForItemAtIndexPath:(NSIndexPath *)indexPath;
@optional
/* 容器视图有多少个组,默认返回1 */
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView;
/* 设置顶部视图和底部视图,通过kind参数分辨是设置顶部还是底部 */
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView 
           viewForSupplementaryElementOfKind:(NSString *)kind 
                                 atIndexPath:(NSIndexPath *)indexPath;

UICollectionViewDelegate

数据无关的view的外形啊,用户交互啊什么的,由UICollectionViewDelegate来负责:

  • cell的高亮
  • cell的选中状态
  • 可以支持长按后的菜单
// UICollectionViewDelegateFlowLayout的常用布局方法
/* 设置每个方块的尺寸大小 */
- (CGSize)collectionView:(UICollectionView *)collectionView 
                  layout:(UICollectionViewLayout*)collectionViewLayout 
  sizeForItemAtIndexPath:(NSIndexPath *)indexPath;
/* 设置方块视图和边界的上下左右间距 */
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView 
                        layout:(UICollectionViewLayout*)collectionViewLayout 
        insetForSectionAtIndex:(NSInteger)section;

参考:

UICollectionView之自定义Layout

iOS学习笔记33 UICollectionView入门

UICollectionView基础API笔记及应用实践

UICollectionView 使用方法总结

上一篇 下一篇

猜你喜欢

热点阅读