NSCollectionView自定义布局启用滚动 [英] NSCollectionView custom layout enable scrolling

查看:397
本文介绍了NSCollectionView自定义布局启用滚动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法垂直和水平滚动以使用NSCollectionView的自定义布局. 根据文档,在我的子类中,我返回collectionViewContentSize,如果该值太大,则在集合视图的封闭滚动视图中自动启用滚动.但是,即使我对水平行中的所有元素进行排序,也只能启用垂直滚动.

I can't get scrolling both vertically and horizontally to work with a custom layout for NSCollectionView. According to the docs, in my subclass I return the collectionViewContentSize and if that is too big, scrolling is automatically enabled in the enclosing scroll view of the collection view. However, even if I order all elements in a horizontal row, only vertical scrolling is enabled.

这是屏幕截图:

这是我的布局代码:

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
}
}

推荐答案

此错误仍在继续.我已经将Bo Yuan的讨厌的技巧转换为Swift. (没有违法行为,Bo Yuan,这不是您的错,我们必须做这个可怕的解决方法!尽管有正式的修复程序,我仍然会删除此代码.暂时,这只是为了保持我的开发努力)

This bug is still ongoing. I've converted Bo Yuan's nasty hack to Swift. (No offence, Bo Yuan, it's not YOUR fault we have to do this horrible workaround! I'm still ripping this code out as soon as there's an official fix though. For the time being this is just going to keep my development efforts going.)

class HackedCollectionView: NSCollectionView {
    override func setFrameSize(_ newSize: NSSize) {
        let size = collectionViewLayout?.collectionViewContentSize ?? newSize
        super.setFrameSize(size)
        if let scrollView = enclosingScrollView {
            scrollView.hasHorizontalScroller = size.width > scrollView.frame.width
        }
    }
}

请注意,这肯定需要尽快处理,因为滚动时动画的每一帧都会调用它.不太好.请,请,请有人解决此问题或找到合适的解决方案.无法水平滚动太荒谬了.

Note that this definitely needs to go ASAP because it's getting called for every single frame of animation when scrolling. Not nice. Please, please, please someone either fix this issue or find a proper solution. Not being able to scroll horizontally is ridiculous.

这篇关于NSCollectionView自定义布局启用滚动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆