重要提示
随着 OS X 10.11 的发布,Apple 推出了一版与 `UICollectionView` 类似的 API 的新版本 `
NSCollectionView
`。我建议对于任何新 10.11+ 项目,使用 `NSCollectionView
`。此库仍然是面向需要向后兼容项目的资源。此项目已被非官方弃用。
JNWCollectionView
是一个为 Mac 设计的现代集合视图,拥有极灵活的 API。单元格按需出列,内存使用量保持在最低。默认情况下,集合视图由图层支持,性能进行了高度优化。
熟悉 `UICollectionView
` 的人应该会感到很自在使用 `JNWCollectionView
`。与 `UICollectionView
` 类似,`JNWCollectionView
` 使用布局类概念来决定屏幕上项目应如何显示。
理解此框架能做什么的最简单方法就是通过示例进行尝试。让我们开始。
如果您只想知道如何下载此项目,请参见 下面的内容。
JNWCollectionView
需要 OS X 10.8+。
JNWCollectionView
继承自 `NSScrollView
`,因此可以通过代码实例化,也可以在 Interface Builder 中实现。以下示例通过代码创建集合视图。
首先,确保您已链接到 `JNWCollectionView
框架并已导入头文件。
#import <JNWCollectionView/JNWCollectionView.h>
// Create the collection view
JNWCollectionView *collectionView = [[JNWCollectionView alloc] initWithFrame:self.view.bounds];
collectionView.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
[self.view addSubview:collectionView];
与 UI/NSTable/CollectionView 一样,需要数据源。确保类符合 `JNWCollectionViewDataSource
`。
@interface SomeViewController : NSViewController <JNWCollectionViewDataSource>
然后类可以为自己设置数据源。
collectionView.dataSource = self;
JNWCollectionView
默认不选择布局类。包括两个布局类(将在以后描述)。对于此示例,我们选择网格布局。但是,布局类旨在被继承,因此您不仅仅局限于内置布局。
JNWCollectionViewGridLayout *gridLayout = [[JNWCollectionViewGridLayout alloc] init];
// The grid layout has its own delegate, so if we want to implement the delegate methods
// we need to conform to JNWCollectionViewGridLayoutDelegate.
gridLayout.delegate = self;
// Tell the grid layout the size of our cells.
gridLayout.itemSize = CGSizeMake(100, 100);
// Set the grid layout as the collection view layout, or the layout
// that is used for positioning the items in the collection view.
collectionView.collectionViewLayout = gridLayout;
接下来,我们可以创建一个继承自 `JNWCollectionViewCell
` 的自定义单元格。我们需要注册此类以便在出列单元格时使用。
[collectionView registerClass:MyCustomCell.class forCellWithReuseIdentifier:@"some identifier"];
几乎完成。让我们实现所需的数据源方法。
- (JNWCollectionViewCell *)collectionView:(JNWCollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
MyCustomCell *cell = (MyCustomCell *)[collectionView dequeueReusableCellWithIdentifier:@"some identifier"];
// customize cell here
return cell;
}
- (NSUInteger)collectionView:(JNWCollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return 200;
}
就这样。让我们调用初始重新加载。
[collectionView reloadData];
现在您已经拥有了一个功能齐全的集合视图。但这只是冰山一角。请查看演示项目并亲自体验,否则请继续阅读。
重要提示
以下关于
NSCollectionView
的评论并不适用于 Apple 在 10.11 中引入的NSCollectionView
的新版本。以下提到的缺点不再相关。
遗憾的是,NSCollectionView
被忽视了。 NSCollectionView
完全没有尝试重用单元格,这意味着它会显示每个单元格,即使它不在屏幕上。它无法处理带有图层支持的,因此滚动性能很差。它也不是很可定制的。
NSTableView
是一个设计良好的类,但它并不是完美的。例如,在 OS X 的较新版本中,它强制启用 Auto Layout。它不容易定制,并且对其遗留的支持附带了大量当前 API 的负担。虽然滚动性能相当不错,但还有改进的空间。
相反,JNWCollectionView
从一开始就被设计成尽可能快和轻量,结合了带有图层支持的视图和优化的单元格回存,通过不懈的剖析和调优而精制。尽管滚动性能可能还有更多的改进空间,但 JNWCollectionView
已达到了纯 AppKit 可能做到的极限。没有任何遗留的负担——这是从头开始为了速度和易用性而设计的。
如引言所述,JNWCollectionView
完全基于布局的概念。集合视图在同一时间内只能有一个布局。布局负责确定项目应该被放置的位置,然而 它不触碰视图图层本身。这种区分在于“项目”和“单元格”,其中项目代表视图本身的数据表示,如框架、alpha 值、索引路径等。单元格本身是视图。
因此,JNWCollectionViewLayout
子类负责确定如何在集合视图中布局 项目,以及其他补充视图。集合视图本身处理视图。
布局还负责处理选择的一些方面。选择可以通过鼠标 和 键盘触发。JNWCollectionView
有一个辅助 API,试图尽可能简单地进行选择事件的处理。
因此,要用 JNWCollectionView
实现任何强大功能,必须使用布局子类。已包含两个(列表和网格),但如果需要,可以创建更多布局。有关如何子类化 JNWCollectionViewLayout
的示例,请参阅 JNWCollectionViewListLayout
和 JNWCollectionViewGridLayout
。头部包含完整的文档和子类化建议。
单元格构建在 JNWCollectionViewCell
类之上。有许多方便的方法可供使用。
每个 JNWCollectionViewCell
实例默认有两个子视图。一个是背景视图,不能直接修改。相反,可以通过设置相关的属性(backgroundImage
和 backgroundColor
)来定制一个图像或颜色。
另一个子视图是 contentView
。应将添加到单元格的任何子视图添加到这个视图中,以确保它与背景视图的正确顺序。
每个 `JNWCollectionViewCell
` 都包含一个 `NSObjectController
` 和一个 `id objectValue
`,可用于数据绑定。利用这种数据绑定的最简单方法是在您的 `JNWCollectionViewCell
` Nib 文件中添加一个 `NSObjectController
`,然后将视图绑定到添加的 `NSObjectController
`。在 Interface Builder 中设置 `NSObjectController
` 的 `Class Name
` 也许会有所帮助。如果您不使用 nib,则可以在 `collectionView:cellForItemAtIndexPath:
` 中手动设置单元格上的 `NSObjectController
`。如果需要,`objectValue
` 属性也可以用于数据绑定。请参阅演示项目中的绑定演示以获取示例。
许多更多的方法和细节可以在头文件中找到。
辅助视图是可重复使用的视图,它们通过“类型”标识符区分。在单个部分中,每种“类型”只能有一个辅助视图。这并不意味着您在每个部分中仅限于一个辅助视图。相反,如果需要多个辅助视图,它们应注册在单独的类型下。
所有辅助视图都建立在 `JNWCollectionViewReusableView
` 之上。有关更多详细资料,请参阅头文件。
请查看头文件本身,因为文档很详细。
JNWCollectionView
具有外部依赖。当您克隆项目时,请确保递归克隆项目以拉取子模块。
git clone --recursive https://github.com/jwilling/JNWCollectionView.git
您有框架后,下一步是将框架链接到您的应用程序。最简单的方法是将 `JNWCollectionView
` 作为您的项目的子项目链接为目标依赖项。如果感到困惑,演示应用程序演示了正确链接到框架的方法。
这是我为苹果公司2013年WWDC奖学金创建的应用。它主要编写来展示我的集合视图能做什么,因此我决定公开其源代码,其中大部分是在一天内编写的。它演示了一个自定义布局类,该类创建时间线排列。线由辅助视图组成,而文本、图像和选择点都是单元格。屏幕上每一行的响应都是一个部分。如果这个存储库中的演示在复杂性方面不太令人印象深刻,那么运行这个应用程序并检查布局类。它可以在这里找到。
JNWCollectionView
根据MIT许可证授权。请参阅LICENSE.md。
简而言之,我制作它是为了帮助尽可能多的人。如果您发现它有用,请告诉我!这可能会让我的日子变得更好。
您可以在推特上关注我,链接为@willing,通过我GitHub个人资料上列出的邮箱联系我,或者阅读我的博客jwilling.com。如果您有任何问题,请在这里的GitHub上发帖或直接在推特上@我。