Objective c NSCollectionView是将NSCollectionViewItems绘制在彼此的上方
我的NSCollection视图正在将我的NSCollection项相互绘制。 更新:我添加了一个示例项目 更新:这有所改变 更新 我当前的示例有两个视图,它们当前位于自己的nib文件中,其中包含专用的Objective c NSCollectionView是将NSCollectionViewItems绘制在彼此的上方,objective-c,macos,autolayout,nscollectionview,nscollectionviewitem,Objective C,Macos,Autolayout,Nscollectionview,Nscollectionviewitem,我的NSCollection视图正在将我的NSCollection项相互绘制。 更新:我添加了一个示例项目 更新:这有所改变 更新 我当前的示例有两个视图,它们当前位于自己的nib文件中,其中包含专用的NScollectionViewItem对象,它们当前用于测试的对象相同。我基本上有一个NSCollectionViewItem,它的子视图中有一个NSTextField。有了所有的限制 对于集合视图,它被设置为网格控制器,理想情况下,我希望有1列 为了加载数据,我将我的ViewControl
NScollectionViewItem
对象,它们当前用于测试的对象相同。我基本上有一个NSCollectionViewItem,它的子视图中有一个NSTextField。有了所有的限制
对于集合视图,它被设置为网格控制器,理想情况下,我希望有1列
为了加载数据,我将我的ViewController设置为NSCollectionViewDataSource,并实现了-(NSInteger)collectionView:(NSCollectionView*)collectionView numberOfItemsInSection:(NSInteger)section和-(NSCollectionViewItem*)collectionView:(NSCollectionView*)collectionView
ItemForRepresentedObjectIndexPath:(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
中的View属性连接到NSCollectionViewItem
。除默认约束外,当前没有任何约束
NSCollectionView
网格设置如下:
布局:网格尺寸:最大行数:0最大列数:1最小项大小:
宽度:250高度:150最大项目尺寸:宽度:250高度:150
这是用于设置整个内容的代码,此时不将其绑定到数据源
似乎无论我如何更改设置,甚至将CollectionView类型更改为Flow,都不会改变任何东西,它看起来是一样的
我一直认为这是一个自动布局问题,因为最初有一些自动布局问题,但这些问题都已经解决了
任何帮助都将不胜感激。数据数组应该保存数据,而不是NSCollectionViewItem
s。在collectionView:itemForRepresentedObjectAtIndexPath:
中调用makeItemWithIdentifier:forIndexPath:
。调用registerClass:forItemWithIdentifier:
或Registernb:forItemWithIdentifier:
注册您的类或nib
更多信息,请参阅和的文档
编辑:
提供NSCollectionViewItem
有两种方法
注册表类:forItemWithIdentifier:
。当集合视图需要一个新项时,它将恢复该类NSCollectionViewItem
是NSViewController
的子类,并且NSViewController
查找与类同名的nib。NSCollectionViewItem
是nib的所有者
注册表nb:forItemWithIdentifier:
。当集合视图需要新项时,它将加载此nib。NSCollectionViewItem
是nib中的顶级对象
您将注册器类:forItemWithIdentifier:
与用于注册器的xib:forItemWithIdentifier:混合使用。使用注册表nb:forItemWithIdentifier:或修复xib。我已经解决了它
并制作了一个github回购协议,该协议有一个工作版本
第一件事。由于Willeke对原始xib设置方式的理解,我能够使网格类型正常工作。但最终,如果你能让它做你想做的事情,成长视图是一种更好的视图类型,因为它支持截面、视图之间的距离等。因此,尽管我一开始想使用网格类型,但我将在我的应用程序中实现成长类型
因此,我使用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文件中定义,因此它们很容易修改
唯一脆弱的部分是我计算每个视图的高度的地方,这是唯一脆弱的部分,因为我在示例应用程序中的实现很懒惰。在实际实现中,我将从实际视图中动态获取它们,这样它们就不会与静态数字绑定。已经取得了一些进展!我从情节提要中删除了NSCollectionViewItems,并将它们与自定义类一起放在自己的NIB中。我注册了这些类,并将数组更改为包含标识符。这将在两个单独的列中加载两个视图,即使我将网格设置为一列。当我滚动视图时,两个NSCollectionViewItems又变成了一个。我尝试了你的代码,它工作了。当您从物品中删除所有违禁品时会发生什么?你是如何设置网格布局的?看来我可能一直在想这个都是错的。所以我在GitHub Repo中有一个工作版本,但它使用的是流而不是网格,从来没有按照我预期的方式使用网格。我可以通过使项目大小与视图大小一样大来创建单个列。所以这是一种工作。然而,我想看看我是否能有不同高度的观点谢谢Willeke的评论。我也有同样的想法。所以我对其进行了修改,使NSCollectionViewItems位于具有专用类的独立nib文件中。在视图控制器中,我注册了标识符,并将数组更改为标识符数组。在
itemForRepresentedObjectAtIndex
ImakeItemWi中