一. 簡(jiǎn)述
以可自定義的布局顯示的數(shù)據(jù)項(xiàng)的有序集合财破。
@interface NSCollectionView : NSView
Merging content and layout to create the final appearance
二. 官方屬性方法
// 為收集視圖提供數(shù)據(jù)的對(duì)象
@property (nullable, weak) id<NSCollectionViewDataSource> dataSource API_AVAILABLE(macos(10.11));
@property (nullable, weak) id<NSCollectionViewPrefetching> prefetchDataSource API_AVAILABLE(macos(10.13));
// 委托對(duì)象
@property (nullable, weak) id<NSCollectionViewDelegate> delegate;
// 為收集視圖提供數(shù)據(jù)的數(shù)組
@property (copy) NSArray<id> *content;
@property (nullable, strong) NSView *backgroundView API_AVAILABLE(macos(10.11));
// 背景色數(shù)組
@property (null_resettable, copy) NSArray<NSColor *> *backgroundColors;
// 背景視圖是否隨項(xiàng)目及其他內(nèi)容滾動(dòng)
@property BOOL backgroundViewScrollsWithContent API_AVAILABLE(macos(10.12));
// 構(gòu)建集合視圖內(nèi)容的布局對(duì)象
@property (nullable, strong) __kindof NSCollectionViewLayout *collectionViewLayout API_AVAILABLE(macos(10.11));
!!! 之后再補(bǔ)充 !!!
三. 示例
1. 效果圖
要達(dá)到的效果:
- 顯示左側(cè)聊天列表
- Split滑動(dòng)item內(nèi)控件位置不變動(dòng)
- 全屏下的顯示
- 點(diǎn)擊item調(diào)整選中色
如下圖
效果圖
2. 具體代碼
2.1 創(chuàng)建NSCollectionView
此處為了方便使用Storyboard
創(chuàng)建
創(chuàng)建CollectionView
2.2 配置flowLayout(可以創(chuàng)建或者代理設(shè)置)
self.flowLayout = [[NSCollectionViewFlowLayout alloc] init];
self.flowLayout.itemSize = NSMakeSize(self.collectionView.frame.size.width, 60); // item大小
self.flowLayout.minimumLineSpacing = 0; // 最小橫向間距
self.flowLayout.minimumInteritemSpacing = 0; // 最小豎向間距
self.collectionView.collectionViewLayout = self.flowLayout;
說(shuō)明: 這里不使用Storyboard
或者代理配置flowLayout的原因是在滑動(dòng)SplitView的時(shí)候要調(diào)整itemSize
萌丈,使用這種方式更方便設(shè)置itemSize
。
2.3 設(shè)置代理
@interface FSMessageVC ()
<
NSSplitViewDelegate,
NSCollectionViewDelegate,
NSCollectionViewDataSource,
NSCollectionViewDelegateFlowLayout
>
self.collectionView.delegate = self;
self.collectionView.dataSource = self;
2.4 設(shè)置CollectionView屬性
// 設(shè)置CollectionView的背景色
self.collectionView.layer.backgroundColor = NSColor.whiteColor.CGColor;
self.collectionView.wantsLayer = YES;
// 設(shè)置可選擇 W!访诱!注意!:巍触菜!不設(shè)置為YES會(huì)導(dǎo)致點(diǎn)擊item無(wú)效果
self.collectionView.selectable = YES;
2.5 注冊(cè)自定義的Item
[self.collectionView registerNib:[[NSNib alloc] initWithNibNamed:@"FSChatCell" bundle:nil]
forItemWithIdentifier:@"kChatItem"];
2.6 實(shí)現(xiàn)代理方法
// 區(qū)數(shù)
- (NSInteger)numberOfSectionsInCollectionView:(NSCollectionView *)collectionView {
return 1;
}
// item數(shù)量
- (NSInteger)collectionView:(NSCollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return self.dataSource.count;
}
// FSChatCell繼承自NSCollectionViewItem
- (nonnull NSCollectionViewItem *)collectionView:(nonnull NSCollectionView *)collectionView itemForRepresentedObjectAtIndexPath:(nonnull NSIndexPath *)indexPath {
FSChatCell *cell = (FSChatCell *)[collectionView makeItemWithIdentifier:@"kChatItem" forIndexPath:indexPath];
cell.name = self.dataSource[indexPath.item];
return cell;
}
- (BOOL)commitEditingAndReturnError:(NSError *__autoreleasing _Nullable * _Nullable)error {
return YES;
}
- (void)encodeWithCoder:(nonnull NSCoder *)coder {
}
2.7 Split滑動(dòng)item內(nèi)控件位置不變動(dòng)
// 1. 添加NSSplitViewDelegate
self.splitView.delegate = self;
// 最小可滑動(dòng)的點(diǎn)
- (CGFloat)splitView:(NSSplitView *)splitView constrainMinCoordinate:(CGFloat)proposedMinimumPosition ofSubviewAt:(NSInteger)dividerIndex {
return 200;
}
// 最大可滑動(dòng)的點(diǎn)
- (CGFloat)splitView:(NSSplitView *)splitView constrainMaxCoordinate:(CGFloat)proposedMaximumPosition ofSubviewAt:(NSInteger)dividerIndex {
return 300;
}
// 滑動(dòng)時(shí)的通知代理, 設(shè)置itemSize
- (void)splitViewDidResizeSubviews:(NSNotification *)notification {
self.flowLayout.itemSize = NSMakeSize(self.collectionView.frame.size.width, 60);
}
2.8 全屏下的顯示
添加全屏通知在通知的回調(diào)方法里調(diào)用 self.flowLayout.itemSize = NSMakeSize(self.collectionView.frame.size.width, 60);
,比較簡(jiǎn)單不再累述哀峻。
2.9 點(diǎn)擊item調(diào)整選中背景色
有兩種方式實(shí)現(xiàn):
-
didSelectItemsAtIndexPaths
和didDeselectItemsAtIndexPaths
修改item背景色 - 在自定義item中重寫(xiě)
selected
方法
// 方式 1
- (void)collectionView:(NSCollectionView *)collectionView didSelectItemsAtIndexPaths:(NSSet<NSIndexPath *> *)indexPaths {
NSIndexPath *indexPath = indexPaths.allObjects.firstObject;
FSChatCell *cell = (FSChatCell *)[collectionView itemAtIndexPath:indexPath];
cell.view.wantsLayer = YES;
cell.view.layer.backgroundColor = NSColor.lightGrayColor.CGColor;
}
- (void)collectionView:(NSCollectionView *)collectionView didDeselectItemsAtIndexPaths:(NSSet<NSIndexPath *> *)indexPaths {
NSIndexPath *indexPath = indexPaths.allObjects.firstObject;
FSChatCell *cell = (FSChatCell *)[collectionView itemAtIndexPath:indexPath];
cell.view.wantsLayer = YES;
cell.view.layer.backgroundColor = NSColor.whiteColor.CGColor;
}
// 方式 2
// FSChatCell.m
- (void)viewDidLoad {
[super viewDidLoad];
self.view.wantsLayer = YES;
self.view.layer.backgroundColor = NSColor.whiteColor.CGColor;
}
- (void)setSelected:(BOOL)selected {
super.selected = selected;
[self changeBgViewColor];
}
- (void)changeBgViewColor {
if (self.selected) {
if (self.highlightState == NSCollectionViewItemHighlightForSelection) {
self.view.layer.backgroundColor = NSColor.lightGrayColor.CGColor;
} else if (self.highlightState == NSCollectionViewItemHighlightNone ||
self.highlightState == NSCollectionViewItemHighlightForDeselection) {
self.view.layer.backgroundColor = NSColor.whiteColor.CGColor;
}
} else {
self.view.layer.backgroundColor = NSColor.whiteColor.CGColor;
}
}
2.10 FSChatCell.xib
說(shuō)明:
- 創(chuàng)建
Object
對(duì)象并綁定FSChatCell
image-20201109174544750
- 連線時(shí)最好將控件連在創(chuàng)建的Objects-ChatCell上
image-20201109174737345
2.11 添加頭/尾
-
創(chuàng)建
FSChatHeaderView
FSChatHeaderView
繼承自NSView
-
注冊(cè)HeaderView
[self.collectionView registerNib:[[NSNib alloc] initWithNibNamed:@"FSChatHeaderView" bundle:nil] forSupplementaryViewOfKind:NSCollectionElementKindSectionHeader withIdentifier:@"kChatHeader"];
實(shí)現(xiàn)代理
- (NSSize)collectionView:(NSCollectionView *)collectionView layout:(NSCollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section {
return NSMakeSize(self.collectionView.frame.size.width, 40);
}
- (NSView *)collectionView:(NSCollectionView *)collectionView
viewForSupplementaryElementOfKind:(NSCollectionViewSupplementaryElementKind)kind
atIndexPath:(NSIndexPath *)indexPath {
FSChatHeaderView *headerView = [collectionView makeSupplementaryViewOfKind:NSCollectionElementKindSectionHeader
withIdentifier:@"kChatHeader"
forIndexPath:indexPath];
return headerView;
}
說(shuō)明:
-
registerNib
/registerClass
可以寫(xiě)成宏涡相,代碼可以更整潔。
#pragma mark - 注冊(cè)Nib
#define kRegisterNibCollectionView(collectionView, cell, indetifier) [collectionView registerNib:[[NSNib alloc] initWithNibNamed:NSStringFromClass([cell class]) bundle:nil] forItemWithIdentifier:indetifier]
#define kRegisterNibTableView(tableView, cell, indetifier) [tableView registerNib:[[NSNib alloc] initWithNibNamed:NSStringFromClass([cell class]) bundle:nil] forCellReuseIdentifier:indetifier]
-
identifier可以寫(xiě)成靜態(tài)常量
static NSString *const kChatItemID = @"chatItemID"; static NSString *const kChatHeaderID = @"chatHeaderID";
MVC/MVP/MVVM模式自己選擇剩蟀,Demo使用MVC完成催蝗。
Demo只設(shè)置了頭部,尾部同理育特。
個(gè)人博客: ?? ForgetSou