首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSCollectionView sizeForItemAt在尝试引用其集合中的项时始终返回异常

NSCollectionView sizeForItemAt在尝试引用其集合中的项时始终返回异常
EN

Stack Overflow用户
提问于 2017-09-19 02:33:56
回答 1查看 364关注 0票数 2

上下文-

我正在开发一个macOS菜单栏应用程序,它显示项目的集合。这些项存在于集合视图中,并包含一个文本字段。

现在,集合视图布局的高度固定为50,我正在尝试根据文本字段的大小动态增加单元格的大小。

我相信最好的方法是在sizeForItemAt方法中,但是我似乎不能引用一个单元格及其文本字段来计算和返回它的高度。每当我在这一点上尝试获取collectiomView项时,应用程序都会崩溃并出现[General] *** -[__NSArrayM objectAtIndex:]: index 1 beyond bounds [0 .. 0]异常。

我的代码-

我的viewDidLoad,我在这里“配置”我的CollectionView

代码语言:javascript
复制
override func viewDidLoad() {
    super.viewDidLoad()

    configureCollectionView()
    ....
}

private func configureCollectionView() {
    let flowLayout = NSCollectionViewFlowLayout()

    flowLayout.itemSize.width = self.view.frame.width
    flowLayout.minimumLineSpacing = 8
    thoughtsCollectionView.collectionViewLayout = flowLayout
    view.wantsLayer = true
}

这就是我试图动态设置高度的地方(也是崩溃的地方)。

代码语言:javascript
复制
func collectionView(_ collectionView: NSCollectionView, layout collectionViewLayout: NSCollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> NSSize {

    guard collectionView.item(at: indexPath) != nil else { // <-- CRASHES HERE
        return NSSize(width: self.view.frame.width, height: 50)
    }

    return self.collectionView.item(at: indexPath)?.textField?.frame.height
}

这就是我向collectionView添加项目的方式

代码语言:javascript
复制
func collectionView(_ collectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath) -> NSCollectionViewItem {

    let item = collectionView.makeItem(withIdentifier: "CollectionViewItem", for: indexPath as IndexPath)
    guard let collectionViewItem = item as? CollectionViewItem else {return item}

    (item as! CollectionViewItem).textField?.stringValue = "Some Text"

    (item as! CollectionViewItem).delegate = self

    return item
}

所以,让我感到奇怪的是,在我的collectionView(_ collectionView: NSCollectionView, didSelectItemsAt indexPaths: Set<IndexPath>)中,我可以通过执行以下操作来成功获取该项目

代码语言:javascript
复制
func collectionView(_ collectionView: NSCollectionView, didSelectItemsAt indexPaths: Set<IndexPath>) {

    guard let indexPath = indexPaths.first else {
        return
    }

    guard collectionView.item(at: indexPath) != nil else {
        return
    }

    let item = collectionView.item(at: indexPath) as! CollectionViewItem // <--- This gets me an item fine

所以我不知道为什么我要和sizeForItemAt作斗争。我有一种感觉,这是因为项目还不存在(并且是在视图开始显示它们时创建的),但是不确定如何正确地处理这种动态调整。

EN

回答 1

Stack Overflow用户

发布于 2019-12-13 17:29:20

我遇到了同样的问题。通过阅读文档,我发现苹果的意图是让我们使用NSCollectionViewLayout而不是商品。

如果您不知道如何处理NSCollectionViewLayout,可以尝试使用数据模型重新生成视图并进行计算。

例如,如果您有一个图像、一个可变大小标签和一个固定大小标签。如: Image |可变标签|标签

您可以像这样重新生成可变标签。

代码语言:javascript
复制
func collectionView(_ collectionView: NSCollectionView, layout collectionViewLayout: NSCollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> NSSize {

    let imageViewWidth:CGFloat = 20 + 64 + 20
    let account = self.dataObject[indexPath]
    let defaultLabelWidth:CGFloat = {
        if account.isDefault {
            let defaultLabel = NSTextField(labelWithString: NSLocalizedString("Default", comment: ""))
            defaultLabel.font = NSFont.systemFont(ofSize: 16.0)
            defaultLabel.sizeToFit()

            return 20 + defaultLabel.bounds.width + 20
        }

        return 0 + 0 + 20
    }()

    let nameLabelWidth:CGFloat = {
        let label = NSTextField(labelWithString: account.name)
        label.font = NSFont.systemFont(ofSize: 16.0)
        label.sizeToFit()

        return label.bounds.width
    }()

    return NSSize(width: imageViewWidth + nameLabelWidth + defaultLabelWidth, height: 80)
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46286020

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档