上下文 -
我正在开发一个显示项目集合的macOS菜单栏应用程序。这些项目存在于集合视图中并包含文本字段。
现在,集合视图布局的固定高度为50,我试图根据文本字段的大小动态增加单元格的大小。
我认为最好的方法是使用sizeForItemAt
方法,但我似乎无法引用单元格及其文本字段来计算并返回它的高度。每当我尝试获取collectiomView项目时,应用程序崩溃时会出现[General] *** -[__NSArrayM objectAtIndex:]: index 1 beyond bounds [0 .. 0]
异常。
我的代码 -
我的viewDidLoad,我在其中'配置'我的CollectionView
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
}
这是我试图动态设置高度(以及它崩溃的地方)
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
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>)
我是通过这样做来成功获得该项目
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
挣扎。我有一种感觉,因为这些项目尚不存在(并且在视图开始显示时创建),但不确定如何正确处理这种动态大小调整。
答案 0 :(得分:0)
我遇到同样的问题。通过阅读文档,我发现Apple打算让我们使用NSCollectionViewLayout
代替项目。
如果您不知道如何处理NSCollectionViewLayout
,则可以尝试使用数据模型来重新生成视图并进行计算。
例如,如果您有一张图像,一个可变尺寸标签和一个固定尺寸标签。喜欢:图片|可变标签|标签
您可以像这样重新生成可变标签。
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)
}