2010-01-21 81 views
8

我有一个NSCollectionView包含CustomViews的集合。最初它将子视图平铺成像网格一样的列和行。然后我将IB中的Columns属性设置为1,所以现在它只是按行显示它们。但是,尽管我的CustomView的宽度是400像素,但它已设置为自动调整大小,NSCollectionView的宽度为400像素,并且它设置为1列,子视图的宽度大约为80像素。NSCollectionView可以自动调整其子视图的宽度以显示一列

我知道我可以通过调用解决这个问题:

CGFloat width = collectionView.bounds.size.width; 
NSSize size = NSMakeSize(width, 85); 
[collectionView setMinItemSize:size]; 
[collectionView setMaxItemSize:size]; 

但将这个代码在我WindowControllerawakeFromNib方法只在程序启动时设置正确的宽度。当我调整窗口大小(并且按照我指定的方式自动调整大小时),CustomViews保持其最初设定的宽度。

如果需要,我很乐意照顾自己调整子视图的大小,但对于Cocoa我很新,而且似乎找不到解释如何做这种事情的任何文章。有人能指引我朝着正确的方向吗?

安东尼

+0

现在已经发现,我可以将我的WindowController设置为Window的委托并通过windowDidResize接收调整大小通知。 所以我现在用的每一个调整窗口大小来设置最大和最小的商品尺寸的时间上面的代码。 能正常工作的窗口增长,但由于某些原因增加最小/最大的商品尺寸导致的CollectionView的边界从不缩水,即使窗口一样。 因此,即使视觉上的CollectionView作为收缩时我调整窗口的大小,它的界限从来不,还有我的子视图做也不! – littlecharva 2010-01-21 22:04:42

+0

你有没有找到一种方法来自动执行此操作? – tofutim 2014-02-25 16:37:41

回答

-2

马特·加拉格尔的精彩博客Cocoa with Love来解决这个问题。这一周,他分享了像在问题一列视图的绑定细节:

http://cocoawithlove.com/2010/03/designing-view-with-bindings.html

下一篇文章,他承诺分享实现的休息,这应该给你你在做什么寻找。

(我要指出,他是直接的NSView继承并重新实现许多NSCollectionView的功能这似乎是共同的,虽然,不是很多人都喜欢继承NSCollectionView的。)

编辑:似乎他打破了他的诺言......我们从未收到过这个帖子。请参阅下面的tofutim答案。

3

我知道这是一个非常迟到的反应,但我得到了同样的问题,并希望我的解决方案将有助于某人。解决方案是访问封闭滚动视图的边界,而不是集合视图本身。因此,要解决这个问题,你需要更换第一行有:

CGFloat width = collectionView.enclosingScrollView.bounds.size.width; 
+0

宽度设置在哪里? – tofutim 2014-02-25 16:05:52

+0

我试着用awakeFromNib设置它 - 时间的60%左右,这个工作 - 但奇怪的是在当时的另外40%的enclosingScrollView具有0宽度。我觉得XCode在某种程度上缓存了一些东西,并最终在没有正确构建的情况下恢复笔尖。 – tofutim 2014-02-27 16:04:18

9

真正的答案是将maxItemSize设置为0,0(NSZeroSize)。否则,它被计算。

[self.collectionView setMaxItemSize:NSZeroSize]; 

这可以在awakeFromNib中设置。

+0

这非常简单,它完全符合我的需求。我的收藏视图中的项目现在就像我打算的那样用收藏视图调整大小。 – Chris 2014-05-28 02:08:09

1

另一个晚 - 我刚刚转向使用NSTableView并提供delegate方法NSView

自动调整是免费的,一列很容易,它渲染速度更快。

0

比方说你想用一个尺寸200x180px你CollectionViewItem,那么你应该设置:

[myCollectionView setMinItemSize:NSMakeSize(200, 180)]; 
[myCollectionView setMaxItemSize:NSMakeSize(280, 250)]; 

你的最大尺寸应足够大,好看,并给予足够的空间用于拉伸以适应collectionView-宽度。

如果列一个固定数量,你也许可以使用(0,0),但如果你想行和列的动态数字,如我想..你应该设定一个固定的最小尺寸和更大最大尺寸。

0

虽然只要你想,你可能会得到一个集合视图的行为,我认为你有一个设计问题

您应该使用NSTableView并设置为1和列的大小来什么,但“无”。 NSTableView适用于表格数据,再加上它可以回收利用大量项目提高性能的单元。 NSCollectionView更像是一个线性布局,它可以垂直滚动来排列网格中的项目。当列号可以动态改变以允许在屏幕上显示更多项目时通常取决于设备方向和屏幕大小,这很有用。

2

我不能让这与默认布局工作 - 但它是相当容易实现自定义布局:

/// 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 
相关问题