I am experimenting with my own custom layout in NSCollectionView on macOS. Whenever I run my app, I get a layout that is definitely not what I have computed (verified this through lots of calls to print()
). The cells are shifted down by some seemingly arbitrary amount.
However, when I widen the window, the collection view automatically corrects itself, and the layout is what I expect. See the gif demonstration and my custom layout code. What is going on?
class MyLayout: NSCollectionViewLayout { var attr: [NSCollectionViewLayoutAttributes] = [] override var collectionViewContentSize: NSSize { get { if self.collectionView?.frame == nil { return .zero } return NSSize(width: CGFloat(self.collectionView?.frame.width ?? 0), height: CGFloat(self.collectionView?.numberOfSections ?? 0) * 75) } } override func prepare() { super.prepare() print("prepare() \(String(describing: collectionView?.frame))") self.attr = [] let height = CGFloat(75) for s in 0..<(collectionView?.numberOfSections ?? 0) { let width = CGFloat((collectionView?.frame.width ?? 0)) / CGFloat((collectionView?.numberOfItems(inSection: s) ?? 1)) for i in 0..<(collectionView?.numberOfItems(inSection: s) ?? 0) { let attr = NSCollectionViewLayoutAttributes(forItemWith: IndexPath(arrayLiteral: s, i)) var shiftedOrigin = collectionView?.frame.origin ?? .zero shiftedOrigin = shiftedOrigin.applying(CGAffineTransform(translationX: width * CGFloat(i), y: CGFloat(s) * height)) attr.frame = NSRect(origin: shiftedOrigin, size: NSSize(width: width, height: height)) print(attr.frame) self.attr.append(attr) } } } override func layoutAttributesForElements(in rect: NSRect) -> [NSCollectionViewLayoutAttributes] { print("layout attributes for elements IN \(rect)") var returnAttr: [NSCollectionViewLayoutAttributes] = [] for attr in attr { if rect.intersects(attr.frame) { returnAttr.append(attr) } } collectionView?.updateConstraints() return returnAttr } override func layoutAttributesForItem(at indexPath: IndexPath) -> NSCollectionViewLayoutAttributes? { print("layout attributes for elements AT \(indexPath)") for attr in attr { if attr.indexPath == indexPath { return attr } } return nil } override func shouldInvalidateLayout(forBoundsChange newBounds: NSRect) -> Bool { true } }
https://stackoverflow.com/questions/67411691/nscollectionview-custom-layout-odd-behavior May 06, 2021 at 12:04PM
没有评论:
发表评论