NSCollectionView 正在相互绘制 NSCollectionViewItems
NSCollectionView is drawing NSCollectionViewItems over each other
我的 NSCollectionView 正在相互绘制我的 NSCollection 项目。
更新:我添加了一个示例项目
GitHub Sample Project
更新:这已经有所改变
When the app first launches it looks like this
更新
我当前的示例有两个视图,它们当前位于自己的 nib 文件中,具有专用的 NScollectionViewItem
对象,它们目前在测试中是相同的。我基本上有一个 NSCollectionViewItem,它有一个带有 NSTextField 的子视图。具有所有约束条件。
对于集合视图,它被设置为网格控制器,理想情况下,我希望有 1 列。
为了用数据加载它,我制作了 ViewController NSCollectionViewDataSource,并实现了 - (NSInteger)collectionView:(NSCollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
和 - (NSCollectionViewItem *)collectionView:(NSCollectionView *)collectionView
itemForRepresentedObjectAtIndexPath:(NSIndexPath *)indexPath
更新代码
包含完整代码:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[collectionView registerClass:ItemOne.class forItemWithIdentifier:@"Item1"];
[collectionView registerClass:ItemTwo.class forItemWithIdentifier:@"Item2"];
cellArray = [@[@"Item1", @"Item2", @"Item1", @"Item2", @"Item1"] mutableCopy];
}
- (void)setRepresentedObject:(id)representedObject {
[super setRepresentedObject:representedObject];
// Update the view, if already loaded.
}
#pragma mark - NSCollectionViewDatasource -
- (NSInteger)collectionView:(NSCollectionView *)collectionView
numberOfItemsInSection:(NSInteger)section {
// We are going to fake it a little. Since there is only one section
NSLog(@"Section: %ld, count: %ld", (long)section, [cellArray count]);
return [cellArray count];
}
- (NSCollectionViewItem *)collectionView:(NSCollectionView *)collectionView
itemForRepresentedObjectAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"IndexPath: %@, Requested one: %ld", indexPath, [indexPath item]);
NSLog(@"Identifier: %@", [cellArray objectAtIndex:[indexPath item]]);
NSCollectionViewItem *theItem = [collectionView makeItemWithIdentifier:[cellArray objectAtIndex:[indexPath item]] forIndexPath:indexPath];
return theItem;
}
更新
ItemOne 和 ItemTwo 类 都是空的 类,每个的 nib 都有一个 NSCollectionViewItem
,后者又有一个带有标签的视图。视图通过 NSCollectionViewItem
中的视图 属性 连接到 NSCollectionViewItem
。目前没有约束,除了默认的
NSCollectionView
网格设置如下:
Layout: Grid Dimensions: Max Rows: 0 Max Columns: 1 Min Item Size:
Width: 250 Height: 150 Max Item Size: Width: 250 Height: 150
这是设置整个东西的代码,此时没有将它绑定到数据源。
看来无论我怎么改设置,甚至把CollectionView的类型改成Flow都没有改变,看起来都一样
我一直将此作为自动布局问题来处理,因为最初存在一些自动布局问题,但这些问题都已解决。
如有任何帮助,我们将不胜感激。
数据数组应该保存数据而不是 NSCollectionViewItem
s。在 collectionView:itemForRepresentedObjectAtIndexPath:
中你调用 makeItemWithIdentifier:forIndexPath:
。致电 registerClass:forItemWithIdentifier:
或 registerNib:forItemWithIdentifier:
注册您的 class 或笔尖。
NSCollectionView, collectionView:itemForRepresentedObjectAtIndexPath: and makeItemWithIdentifier:forIndexPath: 的文档中有更多信息。
编辑:
有两种方法可以提供NSCollectionViewItem
。
registerClass:forItemWithIdentifier:
。当集合视图需要一个新项目时,它会实例化这个 class。 NSCollectionViewItem
是 NSViewController
的子 class,NSViewController
查找与 class 同名的笔尖。 NSCollectionViewItem
是 nib 的所有者。
registerNib:forItemWithIdentifier:
。当集合视图需要一个新项目时,它会加载这个 nib。 NSCollectionViewItem
是笔尖中的顶级对象。
您将 registerClass:forItemWithIdentifier:
与 xib 混合用于 registerNib:forItemWithIdentifier:
。使用 registerNib:forItemWithIdentifier:
或修复 xib。
我想通了。
并且已经制作了一个 github 版本的回购 Working Version of Collection View Sample Application
第一件事。多亏了 Willeke 掌握了原始 xib 的设置方式,我才能够让 Grid 类型正常工作。但最后,如果你可以让它做你想做的事,那么 Grow 视图是一种更好的视图类型,因为它支持部分,以及视图之间的距离等。所以尽管我开始想要使用 Grid 类型,但我将要实现我应用中的成长类型。
所以我使用 Grow 类型完成了单列视图。
我的成功标准是:
- 它可以支持非统一视图高度(每个自定义视图可以有自己的高度)
- 只有一列,每个自定义视图都会随着视图大小的扩展而扩展。
进入源代码:
@interface ViewController ()
@property NSMutableArray *cellArray;
@property (weak) IBOutlet NSCollectionView *collectionView;
@end
@implementation ViewController
@synthesize cellArray;
@synthesize collectionView;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[collectionView registerClass:ItemOne.class forItemWithIdentifier:@"Item1"];
[collectionView registerClass:ItemTwo.class forItemWithIdentifier:@"Item2"];
cellArray = [@[@"Item1", @"Item2", @"Item1", @"Item2", @"Item1"] mutableCopy];
}
- (void)setRepresentedObject:(id)representedObject {
[super setRepresentedObject:representedObject];
// Update the view, if already loaded.
}
#pragma mark - NSCollectionViewDatasource -
- (NSInteger)numberOfSectionsInCollectionView:(NSCollectionView *)collectionView {
return 1;
}
- (NSInteger)collectionView:(NSCollectionView *)collectionView
numberOfItemsInSection:(NSInteger)section {
// We are going to fake it a little. Since there is only one section
NSLog(@"Section: %ld, count: %ld", (long)section, [cellArray count]);
return [cellArray count];
}
- (NSCollectionViewItem *)collectionView:(NSCollectionView *)collectionView
itemForRepresentedObjectAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"IndexPath: %@, Requested one: %ld", indexPath, [indexPath item]);
NSLog(@"Identifier: %@", [cellArray objectAtIndex:[indexPath item]]);
NSCollectionViewItem *theItem = [collectionView makeItemWithIdentifier:[cellArray objectAtIndex:[indexPath item]] forIndexPath:indexPath];
theItem.representedObject = [cellArray objectAtIndex:[indexPath item]];
return theItem;
}
#pragma mark - NSCollectionViewDelegate -
- (NSSize)collectionView:(NSCollectionView *)collectionView
layout:(NSCollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"%@", indexPath);
NSSize size = NSMakeSize(438, 150);
NSInteger width = 0;
NSInteger height = 0;
NSString *label = [cellArray objectAtIndex:[indexPath item]];
NSRect collectionFrame = [collectionView frame];
width = collectionFrame.size.width;
// TODO: This needs to be based on the actual value of the view instead of hardcoding a number in.
if ([label isEqualToString:@"Item1"]) {
height = 114;
} else if ([label isEqualToString:@"Item2"]) {
height = 84;
}
size = NSMakeSize(width, height);
return size;
}
@end
好了。实施还算不错。 NSCollectionView 中显示的每个自定义视图都在其自己的 NSCollectionViewItem 和 .xib 文件中定义,因此它们很容易修改。
唯一脆弱的部分是我计算每个视图的高度的地方,它之所以脆弱,是因为我在示例应用程序的实现中懒惰了。在实际实现中,我将从实际视图中动态获取它们,这样它们就不会绑定到静态数字。
我的 NSCollectionView 正在相互绘制我的 NSCollection 项目。 更新:我添加了一个示例项目 GitHub Sample Project
更新:这已经有所改变 When the app first launches it looks like this
更新
我当前的示例有两个视图,它们当前位于自己的 nib 文件中,具有专用的 NScollectionViewItem
对象,它们目前在测试中是相同的。我基本上有一个 NSCollectionViewItem,它有一个带有 NSTextField 的子视图。具有所有约束条件。
对于集合视图,它被设置为网格控制器,理想情况下,我希望有 1 列。
为了用数据加载它,我制作了 ViewController NSCollectionViewDataSource,并实现了 - (NSInteger)collectionView:(NSCollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
和 - (NSCollectionViewItem *)collectionView:(NSCollectionView *)collectionView
itemForRepresentedObjectAtIndexPath:(NSIndexPath *)indexPath
更新代码 包含完整代码:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[collectionView registerClass:ItemOne.class forItemWithIdentifier:@"Item1"];
[collectionView registerClass:ItemTwo.class forItemWithIdentifier:@"Item2"];
cellArray = [@[@"Item1", @"Item2", @"Item1", @"Item2", @"Item1"] mutableCopy];
}
- (void)setRepresentedObject:(id)representedObject {
[super setRepresentedObject:representedObject];
// Update the view, if already loaded.
}
#pragma mark - NSCollectionViewDatasource -
- (NSInteger)collectionView:(NSCollectionView *)collectionView
numberOfItemsInSection:(NSInteger)section {
// We are going to fake it a little. Since there is only one section
NSLog(@"Section: %ld, count: %ld", (long)section, [cellArray count]);
return [cellArray count];
}
- (NSCollectionViewItem *)collectionView:(NSCollectionView *)collectionView
itemForRepresentedObjectAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"IndexPath: %@, Requested one: %ld", indexPath, [indexPath item]);
NSLog(@"Identifier: %@", [cellArray objectAtIndex:[indexPath item]]);
NSCollectionViewItem *theItem = [collectionView makeItemWithIdentifier:[cellArray objectAtIndex:[indexPath item]] forIndexPath:indexPath];
return theItem;
}
更新
ItemOne 和 ItemTwo 类 都是空的 类,每个的 nib 都有一个 NSCollectionViewItem
,后者又有一个带有标签的视图。视图通过 NSCollectionViewItem
中的视图 属性 连接到 NSCollectionViewItem
。目前没有约束,除了默认的
NSCollectionView
网格设置如下:
Layout: Grid Dimensions: Max Rows: 0 Max Columns: 1 Min Item Size: Width: 250 Height: 150 Max Item Size: Width: 250 Height: 150
这是设置整个东西的代码,此时没有将它绑定到数据源。
看来无论我怎么改设置,甚至把CollectionView的类型改成Flow都没有改变,看起来都一样
我一直将此作为自动布局问题来处理,因为最初存在一些自动布局问题,但这些问题都已解决。
如有任何帮助,我们将不胜感激。
数据数组应该保存数据而不是 NSCollectionViewItem
s。在 collectionView:itemForRepresentedObjectAtIndexPath:
中你调用 makeItemWithIdentifier:forIndexPath:
。致电 registerClass:forItemWithIdentifier:
或 registerNib:forItemWithIdentifier:
注册您的 class 或笔尖。
NSCollectionView, collectionView:itemForRepresentedObjectAtIndexPath: and makeItemWithIdentifier:forIndexPath: 的文档中有更多信息。
编辑:
有两种方法可以提供NSCollectionViewItem
。
registerClass:forItemWithIdentifier:
。当集合视图需要一个新项目时,它会实例化这个 class。 NSCollectionViewItem
是 NSViewController
的子 class,NSViewController
查找与 class 同名的笔尖。 NSCollectionViewItem
是 nib 的所有者。
registerNib:forItemWithIdentifier:
。当集合视图需要一个新项目时,它会加载这个 nib。 NSCollectionViewItem
是笔尖中的顶级对象。
您将 registerClass:forItemWithIdentifier:
与 xib 混合用于 registerNib:forItemWithIdentifier:
。使用 registerNib:forItemWithIdentifier:
或修复 xib。
我想通了。
并且已经制作了一个 github 版本的回购 Working Version of Collection View Sample Application
第一件事。多亏了 Willeke 掌握了原始 xib 的设置方式,我才能够让 Grid 类型正常工作。但最后,如果你可以让它做你想做的事,那么 Grow 视图是一种更好的视图类型,因为它支持部分,以及视图之间的距离等。所以尽管我开始想要使用 Grid 类型,但我将要实现我应用中的成长类型。
所以我使用 Grow 类型完成了单列视图。
我的成功标准是:
- 它可以支持非统一视图高度(每个自定义视图可以有自己的高度)
- 只有一列,每个自定义视图都会随着视图大小的扩展而扩展。
进入源代码:
@interface ViewController ()
@property NSMutableArray *cellArray;
@property (weak) IBOutlet NSCollectionView *collectionView;
@end
@implementation ViewController
@synthesize cellArray;
@synthesize collectionView;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[collectionView registerClass:ItemOne.class forItemWithIdentifier:@"Item1"];
[collectionView registerClass:ItemTwo.class forItemWithIdentifier:@"Item2"];
cellArray = [@[@"Item1", @"Item2", @"Item1", @"Item2", @"Item1"] mutableCopy];
}
- (void)setRepresentedObject:(id)representedObject {
[super setRepresentedObject:representedObject];
// Update the view, if already loaded.
}
#pragma mark - NSCollectionViewDatasource -
- (NSInteger)numberOfSectionsInCollectionView:(NSCollectionView *)collectionView {
return 1;
}
- (NSInteger)collectionView:(NSCollectionView *)collectionView
numberOfItemsInSection:(NSInteger)section {
// We are going to fake it a little. Since there is only one section
NSLog(@"Section: %ld, count: %ld", (long)section, [cellArray count]);
return [cellArray count];
}
- (NSCollectionViewItem *)collectionView:(NSCollectionView *)collectionView
itemForRepresentedObjectAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"IndexPath: %@, Requested one: %ld", indexPath, [indexPath item]);
NSLog(@"Identifier: %@", [cellArray objectAtIndex:[indexPath item]]);
NSCollectionViewItem *theItem = [collectionView makeItemWithIdentifier:[cellArray objectAtIndex:[indexPath item]] forIndexPath:indexPath];
theItem.representedObject = [cellArray objectAtIndex:[indexPath item]];
return theItem;
}
#pragma mark - NSCollectionViewDelegate -
- (NSSize)collectionView:(NSCollectionView *)collectionView
layout:(NSCollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"%@", indexPath);
NSSize size = NSMakeSize(438, 150);
NSInteger width = 0;
NSInteger height = 0;
NSString *label = [cellArray objectAtIndex:[indexPath item]];
NSRect collectionFrame = [collectionView frame];
width = collectionFrame.size.width;
// TODO: This needs to be based on the actual value of the view instead of hardcoding a number in.
if ([label isEqualToString:@"Item1"]) {
height = 114;
} else if ([label isEqualToString:@"Item2"]) {
height = 84;
}
size = NSMakeSize(width, height);
return size;
}
@end
好了。实施还算不错。 NSCollectionView 中显示的每个自定义视图都在其自己的 NSCollectionViewItem 和 .xib 文件中定义,因此它们很容易修改。
唯一脆弱的部分是我计算每个视图的高度的地方,它之所以脆弱,是因为我在示例应用程序的实现中懒惰了。在实际实现中,我将从实际视图中动态获取它们,这样它们就不会绑定到静态数字。