collection控件用來實現界面的各種自定義布局,最常用其作為橫向、豎向的布局控件。很早之前,系統對于collection的支持并不是很好。所以自己實現了支持自定義布局、自定義cell的collection控件。自定義的collection可以滿足所有的產品特殊需求及動態效果,例如在某些特殊情況下可能需要除選中cell之外的其它cell執行布局動畫等。在collection的基礎之上,我又實現了支持cell拖動、拖離窗體的tabview控件。本文主要介紹自定義collection的設計與實現,后續持續更新多tab的tabview控件。
我有幾張阿里云幸運券分享給你,用券購買或者升級阿里云相應產品會有特惠驚喜哦!把想要買的產品的幸運券都領走吧!快下手,馬上就要搶光了。
產品中的一些實現效果
mac旺旺表情面板,實現grid與橫向布局
mac千牛工作臺用作橫向布局
iOS千牛歷史登錄頁面實現當前選中cell變大并且選中cell總中最中位置校準動效的效果
collection
collection主要包括:繼承scrollview的collectionView,數據源協議collectionViewDataSource,事件響應協議collectoinViewDelegate,布局基類collectoinLayout以及展示單元collectionCellView。
模塊圖如下:
collectionView
collection容器包含指實現collectionViewDataSource、collectoinViewDelegate協議的指針以及collectoinLayout成員,同時維護collectoinCellView的控件重用。
@interface WWCollectionView : NSScrollView// 布局對象@property (retain) WWCollectionViewLayout *layout;// 數據源@property (weak) id dataSource;// 事件響應@property (weak) id delegate;// 重加載數據(void)reloadData;// 重排布(void)invalidateLayout;// 取消返回選中(void)unSelectedAll;// 注冊重用對象(void)registerClass:(Class)cellClass forCellWithReuseIdentifier:(NSString *)identifier;// 對象重用(id)dequeueReusableCellWithReuseIdentifier:(NSString )identifier forIndexPath:(NSIndexPath )indexPath;// 設置選中對象(void)selectItemAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated;// 當前選中對象(NSIndexPath *)selectedItem;// 重加載indexPath item(void)reloadItemsAtIndexPath:(NSIndexPath *)indexPath;// 插入(void)insertItemsAtIndexPath:(NSIndexPath *)indexPath withAnimate:(BOOL)animate;// 刪除(void)deleteItemsAtIndexPath:(NSIndexPath *)indexPath withAnimate:(BOOL)animate;// 重新排列(void)relayoutWithAnimation:(BOOL)animated completion:(void (^)(BOOL finished))completion;// 滾動到aPoint(void)scrollToPoint:(NSPoint)aPoint withAnimate:(BOOL)animate;@end
collectionViewDataSource
collection展示的數據源,由宿主實現。
@protocol WWCollectionViewDataSource // 返回indexPath下標的cell(WWCollectionCellView )collectView:(WWCollectionView )collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath;// 總cell個數(NSInteger)numberOfItemInCollectionView:(WWCollectionView *)collectionView;// cell的數據(id)collectionView:(WWCollectionView )colletionView objectValueAtIndexPath:(NSIndexPath )indexPath;@end
collectoinViewDelegate
collection事件的回調響應,由宿主實現。
@protocol WWCollectionViewDelegate // indexPath元素被選中(void)collectionView:(WWCollectionView )collectionView didSelectItemAtIndexPath:(NSIndexPath )indexPath;// 是否支持選中(BOOL)collectionView:(WWCollectionView )collectionView shouldSelectItemsAtIndexPaths:(NSIndexPath )indexPath;@end
collectoinLayout
collectionCellView的布局方案。
@interface WWCollectionViewLayout : NSObject// 布局基類@property (weak) WWCollectionView *collectionView;// 每個cell元素大小@property (assign) NSSize itemSize;// edgeInsets@property (assign) NSEdgeInsets edgeInsets;// scrollview使用,表示整個畫布大小@property (assign) NSSize viewContentSize;(instancetype)initWithCollectionView:(WWCollectionView *)collectionView;(void)invalidateLayout;// 返回index的cell大小(NSRect)frameForIndexPath:(NSIndexPath *)index total:(NSInteger)total;(NSSize)collectionViewContentSize;@end// 橫向布局控件@interface WWFlowCollectionViewLayout : WWCollectionViewLayout@property (assign) CGFloat headMargin;@property (assign) CGFloat tailMargin;@end// grid布局控件@interface WWGridCollectionViewLayout : WWCollectionViewLayout// 每行多少個@property (assign) NSInteger numberPerRow;@property (assign) CGFloat headMargin;@property (assign) CGFloat tailMargin;@end
@implementation WWFlowCollectionViewLayout
(void)invalidateLayout {NSInteger cellCount = [self.collectionView.dataSource numberOfItemInCollectionView:self.collectionView];CGRect bounds = self.collectionView.bounds;// 畫布寬度CGFloat width = _headMargin + _tailMargin + (cellCount - 1) (self.edgeInsets.left + self.edgeInsets.right) + self.itemSize.width cellCount;if (width < bounds.size.width) {width = bounds.size.width;}self.viewContentSize = NSMakeSize(width, bounds.size.height);[super invalidateLayout];}(NSRect)frameForIndexPath:(NSIndexPath *)index total:(NSInteger)total {CGFloat leftPos = self.headMargin + [index indexAtPosition:0] * (self.itemSize.width + self.edgeInsets.left + self.edgeInsets.right);// 返回cell的rectreturn NSMakeRect(leftPos, self.edgeInsets.top, self.itemSize.width, self.itemSize.height);}@end
collectoinCellView
collection展示的cell控件。
@interface WWCollectionCellView : NSView// 當前cell被選中@property (nonatomic, assign) BOOL selected;// 數據@property (nonatomic, retain) id dataValue;// 使用前重置展示效果(void)reset;@end
新聞熱點
疑難解答