1

我的 NSCollectionView 正在将我的 NSCollection 项目相互绘制。 更新:我添加了一个示例项目 GitHub 示例项目

更新:这已经有所改变 当应用程序首次启动时,它看起来像这样

更新 我当前的示例有两个视图,它们当前位于自己的 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一个带有标签的视图。ViewNSCollectionViewItem通过 中的 view 属性连接到NSCollectionViewItem。目前除了默认限制外没有其他限制

NSCollectionView网格设置如下:

布局:网格尺寸:最大行数:0 最大列数:1 最小项目尺寸:宽度:250 高度:150 最大项目尺寸:宽度:250 高度:150

这是设置整个事物的代码,此时不将其绑定到数据源。

似乎无论我如何更改设置,甚至将 CollectionView 类型更改为 Flow 都不会改变任何内容,它看起来都一样。

我一直将此作为 AutoLayout 问题处理,因为最初存在一些自动布局问题,但这些问题都已解决。

任何帮助将不胜感激。

4

2 回答 2

1

数据数组应该保存数据而不是NSCollectionViewItems。在collectionView:itemForRepresentedObjectAtIndexPath:你打电话makeItemWithIdentifier:forIndexPath:。致电registerClass:forItemWithIdentifier:registerNib:forItemWithIdentifier:注册您的课程或笔尖。

NSCollectionViewcollectionView:itemForRepresentedObjectAtIndexPath:makeItemWithIdentifier:forIndexPath:文档中的更多信息。

编辑:

有两种方法可以提供NSCollectionViewItem.

registerClass:forItemWithIdentifier:. 当集合视图需要一个新项目时,它会实例化这个类。NSCollectionViewItem是一个子类,NSViewControllerNSViewController查找与该类同名的 nib。NSCollectionViewItem是笔尖的所有者。

registerNib:forItemWithIdentifier:. 当集合视图需要一个新项目时,它会加载这个 nib。是 nib 中的NSCollectionViewItem顶级对象。

registerClass:forItemWithIdentifier:与 xib 混合用于registerNib:forItemWithIdentifier:. 使用registerNib:forItemWithIdentifier:或修复 xib。

于 2017-06-17T23:18:35.293 回答
0

我想通了。

并制作了一个 github 存储库,其中包含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 文件中定义,因此它们很容易修改。

唯一脆弱的部分是我计算每个视图的高度的地方,它之所以脆弱只是因为我在示例应用程序的实现中很懒惰。在实际实现中,我将从实际视图中动态获取它们,这样它们就不会绑定到静态数字。

于 2017-06-22T15:37:53.777 回答