我的NSCollectionView
包含CustomViews
的集合。最初,它将子视图平铺为列和行,如网格。然后我将IB中的Columns
属性设置为1,所以现在它只是在行中一个接一个地显示它们。但是,即使我的CustomView
宽度为400px,它设置为自动调整大小,NSCollectionView
为400px宽,并且设置为1列,子视图的宽度约为80px。
我知道我可以通过致电来解决这个问题:
CGFloat width = collectionView.bounds.size.width;
NSSize size = NSMakeSize(width, 85);
[collectionView setMinItemSize:size];
[collectionView setMaxItemSize:size];
但是将此代码放在我awakeFromNib
的{{1}}方法中只会在程序启动时设置正确的宽度。当我调整窗口大小(以及我指定的WindowController
自动调整大小)时,CustomViews将保持其初始设置的宽度。
如果需要,我很乐意自己调整子视图的大小,但我对Cocoa很新,似乎找不到任何解释如何做这样的事情的文章。有人能指出我正确的方向吗?
安东尼
答案 0 :(得分:9)
真正的答案是将maxItemSize设置为0,0(NSZeroSize
)。否则,计算它。
[self.collectionView setMaxItemSize:NSZeroSize];
可以在awakeFromNib
。
答案 1 :(得分:3)
我知道这是一个非常迟到的回复,但我遇到了同样的问题,并希望我的解决方案可以帮助某人。解决方案是访问封闭滚动视图的边界而不是集合视图本身。所以要解决它,你需要用第一行代替:
CGFloat width = collectionView.enclosingScrollView.bounds.size.width;
答案 2 :(得分:2)
我无法使用默认布局 - 但实现自定义布局相当容易:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
$route['default_controller'] = "welcome";
$route['404_override'] = '';
然后您需要的只是
/// Simple single column layout, assuming only one section
class SingleColumnLayout: NSCollectionViewLayout {
/// Height of each view in the collection
var height:CGFloat = 100
/// Padding is wrapped round each item, with double an extra bottom padding above the top item, and an extra top padding beneath the bottom
var padding = EdgeInsets.init(top: 5, left: 10, bottom: 5, right: 10)
var itemCount:Int {
guard let collectionView = collectionView else {
return 0
}
return collectionView.numberOfItems(inSection:0)
}
override func shouldInvalidateLayout(forBoundsChange newBounds: NSRect) -> Bool {
return true
}
override open func layoutAttributesForItem(at indexPath: IndexPath) -> NSCollectionViewLayoutAttributes? {
let attributes = NSCollectionViewLayoutAttributes(forItemWith: indexPath)
guard let collectionView = collectionView else {
return attributes
}
let bounds = collectionView.bounds
let itemHeightWithPadding = height + padding.top + padding.bottom
let row = indexPath.item
attributes.frame = NSRect(x: padding.left, y: itemHeightWithPadding * CGFloat(row) + padding.top + padding.bottom , width: bounds.width - padding.left - padding.right , height: height)
attributes.zIndex = row
return attributes
}
//If you have lots of items, then you should probably do a 'proper' implementation here
override open func layoutAttributesForElements(in rect: NSRect) -> [NSCollectionViewLayoutAttributes] {
var attributes = [NSCollectionViewLayoutAttributes]()
if (itemCount>0){
for index in 0...(itemCount-1) {
if let attribute = layoutAttributesForItem(at: NSIndexPath(forItem: index, inSection: 0) as IndexPath) {
attributes.append(attribute)
}
}
}
return attributes
}
override open var collectionViewContentSize: NSSize {
guard let collectionView = collectionView else {
return NSSize.zero
}
let itemHeightWithPadding = height + padding.top + padding.bottom
return NSSize.init(width: collectionView.bounds.width, height: CGFloat(itemCount) * itemHeightWithPadding + padding.top + padding.bottom )
}
}
答案 3 :(得分:1)
另一个后期 - 我刚刚转而使用NSTableView
并通过NSView
方法提供delegate
。
自动化是免费的,一列很容易,并且渲染速度更快。
答案 4 :(得分:0)
假设您希望CollectionViewItem的大小为200x180px,那么您应该设置:
[myCollectionView setMinItemSize:NSMakeSize(200, 180)];
[myCollectionView setMaxItemSize:NSMakeSize(280, 250)];
你的最大尺寸应该足够大,看起来不错,并提供足够的空间来拉伸以适应collectionView-Width。
如果你有一个固定数量的列,你可以使用(0,0),但如果你想要一个像我想要的动态行数和列数,你应该设置一个固定的最小尺寸和一个更大的最大值.size。
答案 5 :(得分:0)
虽然你可能会得到一个集合视图来表现你想要的行为,但我认为你有一个设计问题
您应该使用NSTableView
并将列设置为1,并将其大小设置为除“无”之外的任何内容。 NSTableView
用于表格数据,此外它还可以回收单元格,从而为大量项目提供出色的性能提升。 NSCollectionView
更像是一个线性布局,它使用垂直滚动来排列网格中的项目。当列号可以动态更改以允许在屏幕上显示更多项目时,它非常有用,通常取决于设备方向和屏幕大小。
答案 6 :(得分:0)
我尝试了这里提出的所有解决方案,但都没有帮助。如果您使用流布局(默认情况下使用),则可以使用以下代码对其进行扩展,并且每次更改都会调用委托的sizeForItem方法
class MyCollectionViewFlowLayout: NSCollectionViewFlowLayout {
override func shouldInvalidateLayout(forBoundsChange newBounds: NSRect) -> Bool {
return true
}
override func invalidationContext(forBoundsChange newBounds: NSRect) -> NSCollectionViewLayoutInvalidationContext {
let context = super.invalidationContext(forBoundsChange: newBounds) as! NSCollectionViewFlowLayoutInvalidationContext
context.invalidateFlowLayoutDelegateMetrics = true
return context
}
}
希望这对某人有帮助,因为我花了两个晚上才找到解决方法
答案 7 :(得分:-4)
Matt Gallagher精彩的博客Cocoa with Love 关于来解决这个问题。本周,他分享了一个单列视图的绑定详细信息,如下所示:
http://cocoawithlove.com/2010/03/designing-view-with-bindings.html
下一个条目,他承诺分享其余的实施,这应该可以为您提供所需的信息。
(我应该注意他是直接子类化NSView并重新实现许多NSCollectionView的功能。这似乎很常见;没有多少人喜欢子类化NSCollectionView。)
编辑:似乎他违背了承诺......我们从来没有收到过那篇文章。请参阅下面的tofutim答案。