代码之家  ›  专栏  ›  技术社区  ›  Displaced Hoser

从NSCollectionView获取当前焦点的文档对象

  •  0
  • Displaced Hoser  · 技术社区  · 9 年前

    我打开了一个(子类化的)NSCollectionView,其中包含多个文本视图。每个文本视图都映射到一个(子类化的)NSDocument对象。(想法是使用文档体系结构的保存功能,而不是其窗口功能,因为我需要在同一窗口中包含多个文档,而传统的文档体系结构不允许这样做。)

    现在,我希望用户能够从主菜单调用一个函数,该函数将影响他们当前选择的文档。也就是说:文档当前在具有当前焦点的文本视图中可见,菜单命令应该对该文档进行更改。但是菜单命令的发送者只是菜单。当窗口控制器从菜单中处理命令时,我如何告诉它当前选择的文档是什么?

    1 回复  |  直到 9 年前
        1
  •  1
  •   rob mayoff    9 年前

    这就是为什么 the responder chain 是的。

    因为你正在使用 NSCollectionView ,您可能已经有了的子类 NSCollectionViewItem 。如果没有,请创建一个。在这个子类中实现您的操作方法。例子:

    class DocumentItem: NSCollectionViewItem {
    
        var document: MyDocument? {
            return representedObject as? MyDocument
        }
    
        @IBAction func doThatThing(sender: AnyObject?) {
            Swift.print("This is where I do that thing to \(document)")
        }
    
        // @IBOutlets and whatnot here...
    
    }
    

    您可能需要将其设置为 NSCollectionViewItem(NSCollection视图项) 在你的xib或故事板中。

    接下来,如果您的单元格视图( NSCollectionViewItem(NSCollection视图项) )不是的自定义子类 NSView 现在,您应该使它成为一个自定义子类。您必须覆盖 acceptsFirstResponder 返回true:

    class DocumentCellView: NSView {
    
        override var acceptsFirstResponder: Bool { return true }
    
        // @IBOutlets and whatnot here...
    
    }
    

    确保将其设置为故事板或xib中细胞视图的自定义类。

    最后,将菜单项的操作连接到 doThatThing: 第一被告:

    connection menu item to first responder

    其工作原理如下:

    因为单元格视图现在返回true 接受第一响应者 ,当用户单击集合视图中的单元格视图时,系统将使其成为 第一响应者 (应答器链的起点)。

    当视图具有视图控制器时,它会使该视图控制器成为响应程序链中继其自身之后的下一个响应程序(如果您使用的是OS X 10.10 Yosemite或更高版本)。您的单元格视图有一个视图控制器:您从中返回的项对象 outlineView:itemForRepresentedObjectAtIndexPath: . ( NSCollectionViewItem(NSCollection视图项) 是的子类 NSViewController ,因此您的自定义项是视图控制器。)

    当用户单击菜单项时,菜单项会询问 NSApplication 从第一个响应者开始,沿着响应者链发送其操作。第一个响应者是细胞视图,但它不响应 doThatThing(做那事): 消息所以 NS应用程序 向视图询问其 nextResponder ,这是您的 NSCollectionViewItem(NSCollection视图项) 子类。那个物体 回应 doThatThing(做那事): 所以 NS应用程序 发送 doThatThing(做那事): 到您的item对象(使用 NSMenuItem 对象作为 sender 参数),并且不检查响应程序链的其余部分。