Hi,
I need to implement a custom NSCollectionViewLayout with support for both horizontal and vertical scrolling, if needed. The WWDC 2015 video and the doc say, that this case is handled by returning the appropriate content size. But I can't get horizontal scrolling to work.
I made a simple test layout that just puts items horizontally next to each other, so that `collectionViewContentSize` returns a width bigger than the screen of my MacBook. Still, the enclosing scrollview only enables vertical scrolling (and `hasHorizontalScroller` is set to yes). I'm using Xcode 7.3 with Swift 2.2, but the issue is also present in Xcode 8 beta 1 with Swift 3.
Here is the code of my layout class:
import Cocoa
class Layout: NSCollectionViewLayout {
var cellSize = CGSize(width: 100, height: 30)
var cellSpacing: CGFloat = 10
var sectionSpacing: CGFloat = 20
private var contentSize = CGSize.zero
private var layoutAttributes = [NSIndexPath: NSCollectionViewLayoutAttributes]()
override func prepareLayout() {
guard let collectionView = collectionView else { return }
let sections = collectionView.numberOfSections
guard sections > 0 else { return }
contentSize.height = cellSize.height
for section in 0..<sections {
let items = collectionView.numberOfItemsInSection(section)
guard items > 0 else { break }
for item in 0..<items {
let origin = CGPoint(x: contentSize.width, y: 0)
let indexPath = NSIndexPath(forItem: item, inSection: section)
let attributes = NSCollectionViewLayoutAttributes(forItemWithIndexPath: indexPath)
attributes.frame = CGRect(origin: origin, size: cellSize)
layoutAttributes[indexPath] = attributes
contentSize.width += cellSize.width + cellSpacing
}
contentSize.width += sectionSpacing
}
}
override var collectionViewContentSize: NSSize {
return contentSize
}
override func layoutAttributesForElementsInRect(rect: NSRect) -> [NSCollectionViewLayoutAttributes] {
return layoutAttributes.values.filter { $0.frame.intersects(rect) }
}
override func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath) -> NSCollectionViewLayoutAttributes? {
return layoutAttributes[indexPath]
}
override func shouldInvalidateLayoutForBoundsChange(newBounds: NSRect) -> Bool {
return false
}
}