【问题标题】:How can I get notified when the user finishes editing a cell in an NSTableView?当用户完成对 NSTableView 中的单元格的编辑时,如何获得通知?
【发布时间】:2008-10-11 15:20:36
【问题描述】:

我需要知道用户何时完成对 NSTableView 中的单元格的编辑。该表包含所有用户的日历(从 CalCalendarStore 获得),因此为了保存用户的更改,我需要将更改通知 CalCalendarStore。但是,在用户完成编辑后,我找不到任何被调用的东西——我猜想在表的委托中会有一个方法,但我只看到一个在编辑开始时被调用的方法,而不是在编辑结束时调用的方法。

【问题讨论】:

    标签: cocoa macos


    【解决方案1】:

    您可以通过使用NSNotificationCenter 或使用NSControl 方法在不继承NSTableView 的情况下获得相同的结果。在此处查看 Apple 文档:

    http://developer.apple.com/library/mac/#qa/qa1551/_index.html

    这只是几行代码,对我来说非常有效。


    如果你可以成为NSTableViewdelegate,你只需要实现方法

    - (void)controlTextDidEndEditing:(NSNotification *)obj { ... }
    

    实际上,NSTableView 是它所包含的NSControl 元素的delegate,并将这些方法调用转发给它的delegate(还有其他有用的方法)

    否则,请使用NSNotificationCenter

    // where you instantiate the table view
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(editingDidEnd:)
        name:NSControlTextDidEndEditingNotification object:nil];
    
    // somewhere else in the .m file
    - (void)editingDidEnd:(NSNotification *)notification { ... }
    
    // remove the observer in the dealloc
    - (void)dealloc {
       [[NSNotificationCenter defaultCenter] removeObserver:self
        name:NSControlTextDidEndEditingNotification object:nil];
       [super dealloc]
    }
    

    【讨论】:

    • 嗯,这是对还是错,这取决于您使用的是基于单元格的表格还是基于视图的表格。如果您使用基于单元格的表格并且您的目标是写出更改,则此方法将不起作用,因为此通知在 tableView:setObjectValue:forTableColumn:row: 方法被调用之前发送将值存储在数据源中,因此您将写出旧值。
    • 实际上我在基于视图的表格视图中根本没有收到此通知
    【解决方案2】:

    子类 NSTableView 并覆盖 textDidEndEditing: (一定要调用 super 的实现)。

    这只会由文本字段 NSTextFieldCell 或 NSComboBoxCell 调用(但仅在通过键入来更改值时,而不是通过从组合菜单中选择值时)。

    【讨论】:

      【解决方案3】:

      使用 addObserver:toObjectsAtIndexes:forKeyPath:options:context: 为内容数组中的每个项目设置观察者:

      您还需要为数组本身设置一个观察者,以便通知您添加到数组中或从数组中删除的对象。

      iSpend 项目为例。

      【讨论】:

        【解决方案4】:

        查看 NSTableDataSource 协议。您要查找的消息称为:tableView:setObjectValue:forTableColumn:row:

        【讨论】:

        • 这可能是正确的答案。话虽如此,它仅适用于基于单元格的表格。如果您使用的是基于视图的表,则永远不会调用该方法。
        【解决方案5】:

        将@Milly 的回答翻译成Swift 3

        // Setup editing completion notifications
        NotificationCenter.default.addObserver(self, selector: #selector(editingDidEnd(_:)), name: NSNotification.Name.NSControlTextDidEndEditing, object: nil)
        

        通知处理函数:

        func editingDidEnd(_ obj: Notification) {
            guard let newName = (obj.object as? NSTextField)?.stringValue else {
                return
            }
        
            // post editing logic goes here
        }
        

        【讨论】:

          【解决方案6】:

          子类 NSArrayController 并覆盖 objectDidEndEditing: (一定要调用 super 的实现)。

          这将主要仅由文本字段 NSTextFieldCell 或 NSComboBoxCell 调用(但仅在通过键入来更改值时,而不是通过从组合菜单中选择值)。可能还有其他一些单元格会调用它,但我不确定是哪些单元格。如果您有自定义单元格,请考虑实施 NSEditor 和 NSEditorRegistration 非正式协议。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-06-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-03-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多