获取 NSCollectionView 中视图的索引?

问题描述 投票:0回答:6

我已经使用其新的基于视图的 NSTableView 为 Mac OS X Lion 开发了一个应用程序,但由于我想将整个应用程序移植到 Snow Leopard,所以我正在尝试找出模拟此类表格视图的最佳方法。到目前为止,我已经创建了一个 NSCollectionView,一切都很好,除了我无法获取触发按钮单击事件的视图的索引。 在 Lion 中我有以下功能:

- (IBAction)buttonClick:(id)sender

所以我可以使用类似的方法(我不记得它的名字)来获取表视图内视图的索引

- (NSInteger)rowForView:(NSView *)aView

aView 是发送者的超级视图,但我找不到集合视图的类似内容......唯一“有用”的方法似乎是

- (NSCollectionViewItem *)itemAtIndex:(NSUInteger)index

(或类似的东西),但这对我没有帮助,因为它返回一个 NSCollectionViewItem,我什至无法访问它,只知道相应的视图!

cocoa indexing nstableview nscollectionview nscollectionviewitem
6个回答
4
投票

在按钮单击中,尝试以下代码:

id collectionViewItem = [sender superview];
NSInteger index = [[collectionView subviews]  indexOfObject:collectionViewItem];
return index;

希望这有帮助:)


2
投票

天啊!这两种方法都有问题。我可以看到第一个如何工作,但请注意“collectionViewItem”实际上是视图,而不是collectionViewItem,它是一个视图控制器。

第二种方法不起作用,除非您对按钮进行子类化并放入到 collectionViewItem 的反向链接。否则,您的视图不知道什么 collectionViewItem 控制它。您应该使用绑定到 collectionViewItem 的representedObject 的选择器来代替,以使操作指向数组中的正确对象。


1
投票

像这样的东西怎么样:

id obj = [collectonViewItem representedObject];
NSInteger index = [[collectionView contents] indexOfObject:obj];

0
投票

正如我在这里建议的:如何处理 NSCollectionView 中的按钮单击

我会这样做(因为你要按下的按钮应该与相应的模型耦合,因此代表对象):

  1. 向 collectionViewItem 的模型添加一个方法(例如,buttonClicked)
  2. 将按钮目标绑定到集合视图项
  3. 绑定时将模型关键路径设置为:representedObject
  4. 绑定时将选择器名称设置为:您之前选择的方法名称(例如buttonClicked)
  5. 如果您必须告诉委托或建立观察者模式,请将协议添加到您的模型中

0
投票
  1. 使用 NSArrayController 绑定到 NSCollectionView,

  2. 使用collectonViewItem.representedObject来获取自己定义的自定义模型。

  3. 在您的自定义模型中保存并获取索引。

这对我有用。


0
投票

这是解决此问题的一种方法:

  • 对于集合视图项,创建一个专用的
    NSView
    子类,并将其用作集合视图项 XIB 中的主容器类。我的意思是你的
    view
    实例的
    NSCollectionViewItem
    属性应该指向这个专用类。
  • 然后,在按钮操作中,您需要找到按钮的超级视图:
    • 上面提到的专用容器类。
    • 集合视图。
    • (您的视图层次结构大致类似于
      collection view > item view > button
      ,因此这两个视图应该始终存在,除非容器不可见。)
  • 获得所有这些信息后,您可以迭代集合视图的
    visibleItems
    。您要找的商品是带有
    item.view == yourContainerView
    的商品。

首先,让我们在

NSView
上创建一个辅助方法:

extension NSView {
    
    /// The receiver or one of its super views matching the given class.
    func enclosingView<T>(type: T.Type) -> T? {
        var cursor: NSView? = self
        
        while let current = cursor {
            if let match = cursor as? T {
                return match
            }
            
            cursor = current.superview
        }
        
        return nil
    }
    
}

使用此功能,搜索项目的工作方式如下:

let button: NSButton = yourButtonInstance
guard
    let container = button.enclosingView(type: YourContainer.self), 
    let collectionView = button.enclosingView(type: NSCollectionView.self),
    let item = collectionView.visibleItems().first(where: { $0.view == container })
else {
    return
}

/// `item` now is the NSCollectionViewItem instance associated with your button.
© www.soinside.com 2019 - 2024. All rights reserved.