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;