2010-01-21 46 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 
相關問題