罐NSCollectionView AUTORESIZE它的子视图的宽度来显示一列
-
22-09-2019 - |
题
我有一个包含NSCollectionView
的集合的CustomViews
。最初,它平铺的子视图到像一个网格列和行。然后我在IB的Columns
属性设置为1,所以现在它只是显示他们陆续在列。然而,即使我CustomView
是400像素宽,它被设置为自动调整大小时,NSCollectionView
是400像素宽,它被设置为1列,子视图绘制大约80px宽。
我知道我可以通过调用解决这个问题:
CGFloat width = collectionView.bounds.size.width;
NSSize size = NSMakeSize(width, 85);
[collectionView setMinItemSize:size];
[collectionView setMaxItemSize:size];
但是,把这个代码在我awakeFromNib
的WindowController
方法只设置正确的宽度的程序启动时。当我调整窗口的大小(以及如我所指定的NSCollectionView
autoresizes),则CustomViews停留在它们的初始设定宽度。
我很高兴地采取调整子视图自己如果需要照顾,但我很新的可可和似乎无法找到解释如何做这样的事情的任何物品。有人可以点我朝着正确的方向吗?
安东尼
解决方案
马特·加拉格尔的精彩博客可可与爱是的关于的要解决这个问题。本周,他共享一列视图的像在问题的绑定信息:
http://cocoawithlove.com/2010/03/designing -view与 - bindings.html
下一篇文章,他承诺将共享实现,这应该给你你要寻找的其余部分。
(我要指出,他直接继承的NSView和重新实现许多NSCollectionView的功能这似乎是共同的,虽然;不是很多人都喜欢继承NSCollectionView的)
编辑:好像他不遵守诺言......我们从来没有收到这个职务。见tofutim的回答下面来代替。
其他提示
在真答案是将maxItemSize设置为0,0(NSZeroSize
)。否则,它被计算出来。
[self.collectionView setMaxItemSize:NSZeroSize];
这可以在设定awakeFromNib
我知道这是一个非常晚回应,但我得到了同样的问题,希望我的解决方案将帮助别人。解决办法是封闭的不收集视图本身滚动视图的访问范围。因此,要解决这个问题,你需要更换第一行有:
CGFloat width = collectionView.enclosingScrollView.bounds.size.width;
我不能让这与默认布局的工作 - 但它是相当容易实现自定义布局:
/// 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 )
}
}
那么所有你需要的是
var layout=SingleColumnLayout()
collectionView.collectionViewLayout = layout
另一个晚一个 - 我刚切换到使用NSTableView
和提供由该方法NSView
一个delegate
来自动调整大小为免费,一列是容易的,它使得大量更快。
比方说,你希望你的CollectionViewItem大小为200x180px,那么你应该设置:
[myCollectionView setMinItemSize:NSMakeSize(200, 180)];
[myCollectionView setMaxItemSize:NSMakeSize(280, 250)];
您最大尺寸应该是足够大好看,并给予足够的空间用于拉伸以适应的CollectionView宽度。
如果您有列固定数量的,你也许可以使用(0,0),但如果你想行和像我想列一个动态的数字..你应该设定一个固定的最小尺寸和大的最大.size。
虽然你可能会得到一个集合视图的行为,只要你想,我觉得你有一个设计问题
您应该使用NSTableView
和列集为1,其尺寸为除“无”。 NSTableView
适用于表格数据,再加上它可以回收细胞,其给出了大量的物品有很大的性能提升。 NSCollectionView
更像是一个线性布局,排列在网格中的项目,有垂直滚动。它是有用的,当列数可以动态地改变,以允许在屏幕上显示多个项目,通常取决于设备的方向和屏幕尺寸。