【问题标题】:Making NSTableView columns sortable via Interface Builder通过 Interface Builder 使 NSTableView 列可排序
【发布时间】:2018-04-11 18:57:09
【问题描述】:

我有一个 NSTableView,我想使用 Interface Builder 方法使其可排序,但我在 Apple 的 Guides and Sample Code 描述如何做到这一点时遇到了麻烦。基于对原始问题的 cmets,我认为该文档已经过时并且指向错误的方向,所以我正在重写我的问题。

在默认的 Cocoa 应用程序模板中添加了以下内容:

class Foo: NSObject {

    @objc dynamic var name : String
    @objc dynamic var colour : String

    override init() {
        name = "name"
        colour = "colour"

        super.init()
    }

    init(_ name : String, _ colour : String) {
        self.name = name
        self.colour = colour

        super.init()
    }
}
class ViewController: NSViewController {

    @objc dynamic var fooList : [Foo] = [Foo("Bar", "Red"),
                                         Foo("Baz", "Green"),
                                         Foo("Beelzebub", "Blue")]

}

我在Main.storyboard 的视图控制器中添加了NSArrayControllerNSTableview。 Array Controller 的“Controller Content”绑定到 View Controller 的 Model Key Path self.fooList,Table View 的“Table Content”绑定到 array controller 的默认数据(Controller Key of arrangedObjects),每个表格视图单元格的“值”绑定到表格单元格视图,“模型键路径”分别为objectValue.nameobjectValue.colour。到目前为止,一切正常,我得到了填充表格视图的数据。

根据 cmets 中的建议,为了使列表可排序,我正在尝试添加“排序描述符”绑定。我已将表视图的“排序描述符”绑定到数组控制器(默认选项),并将数组控制器的排序描述符绑定到视图控制器(添加了self.fooList 的“模型键路径”)。

此时,如果我尝试运行应用程序,我会收到异常并回溯:

2018-04-15 17:45:13.354272-0400 ACTest[48227:16210514] -[ACTest.Foo key]: unrecognized selector sent to instance 0x61000026c900
2018-04-15 17:45:13.356022-0400 ACTest[48227:16210514] [General] An uncaught exception was raised
2018-04-15 17:45:13.356042-0400 ACTest[48227:16210514] [General] -[ACTest.Foo key]: unrecognized selector sent to instance 0x61000026c900
2018-04-15 17:45:13.356105-0400 ACTest[48227:16210514] [General] (
    0   CoreFoundation                      0x00007fff57caffcb __exceptionPreprocess + 171
    1   libobjc.A.dylib                     0x00007fff7e94dc76 objc_exception_throw + 48
    2   CoreFoundation                      0x00007fff57d48a24 -[NSObject(NSObject) doesNotRecognizeSelector:] + 132
    3   CoreFoundation                      0x00007fff57c26610 ___forwarding___ + 1456
    4   CoreFoundation                      0x00007fff57c25fd8 _CF_forwarding_prep_0 + 120
    5   AppKit                              0x00007fff5540eb48 -[NSArrayController automaticRearrangementKeyPaths] + 216
    6   AppKit                              0x00007fff5540e95d -[NSArrayController _updateAutomaticRearrangementKeysPaths] + 30
    7   AppKit                              0x00007fff555706ef -[NSArrayController _didChangeArrangementCriteriaWithOperationsMask:useBasis:] + 53
    8   AppKit                              0x00007fff5557055e -[NSArrayController setSortDescriptors:] + 219
    9   AppKit                              0x00007fff5570a6c4 -[NSControllerConfigurationBinder _updateSortDescriptors:] + 73
    10  AppKit                              0x00007fff5570aa7b -[NSControllerConfigurationBinder _observeValueForKeyPath:ofObject:context:] + 279
    11  AppKit                              0x00007fff55260cff -[NSObject(NSKeyValueBindingCreation) bind:toObject:withKeyPath:options:] + 782
    12  AppKit                              0x00007fff551dcbbd -[NSIBObjectData nibInstantiateWithOwner:options:topLevelObjects:] + 1430
    13  AppKit                              0x00007fff552d813a -[NSNib _instantiateNibWithExternalNameTable:options:] + 679
    14  AppKit                              0x00007fff552d7d96 -[NSNib _instantiateWithOwner:options:topLevelObjects:] + 136
    15  AppKit                              0x00007fff55a2e180 -[NSStoryboard instantiateControllerWithIdentifier:] + 236
    16  AppKit                              0x00007fff551d0ecf NSApplicationMain + 729
    17  ACTest                              0x000000010000497d main + 13
    18  libdyld.dylib                       0x00007fff7f53d115 start + 1
    19  ???                                 0x0000000000000003 0x0 + 3
)
2018-04-15 17:45:13.384522-0400 ACTest[48227:16210514] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[ACTest.Foo key]: unrecognized selector sent to instance 0x61000026c900'
*** First throw call stack:
(
    0   CoreFoundation                      0x00007fff57caffcb __exceptionPreprocess + 171
    1   libobjc.A.dylib                     0x00007fff7e94dc76 objc_exception_throw + 48
    2   CoreFoundation                      0x00007fff57d48a24 -[NSObject(NSObject) doesNotRecognizeSelector:] + 132
    3   CoreFoundation                      0x00007fff57c26610 ___forwarding___ + 1456
    4   CoreFoundation                      0x00007fff57c25fd8 _CF_forwarding_prep_0 + 120
    5   AppKit                              0x00007fff5540eb48 -[NSArrayController automaticRearrangementKeyPaths] + 216
    6   AppKit                              0x00007fff5540e95d -[NSArrayController _updateAutomaticRearrangementKeysPaths] + 30
    7   AppKit                              0x00007fff555706ef -[NSArrayController _didChangeArrangementCriteriaWithOperationsMask:useBasis:] + 53
    8   AppKit                              0x00007fff5557055e -[NSArrayController setSortDescriptors:] + 219
    9   AppKit                              0x00007fff5570a6c4 -[NSControllerConfigurationBinder _updateSortDescriptors:] + 73
    10  AppKit                              0x00007fff5570aa7b -[NSControllerConfigurationBinder _observeValueForKeyPath:ofObject:context:] + 279
    11  AppKit                              0x00007fff55260cff -[NSObject(NSKeyValueBindingCreation) bind:toObject:withKeyPath:options:] + 782
    12  AppKit                              0x00007fff551dcbbd -[NSIBObjectData nibInstantiateWithOwner:options:topLevelObjects:] + 1430
    13  AppKit                              0x00007fff552d813a -[NSNib _instantiateNibWithExternalNameTable:options:] + 679
    14  AppKit                              0x00007fff552d7d96 -[NSNib _instantiateWithOwner:options:topLevelObjects:] + 136
    15  AppKit                              0x00007fff55a2e180 -[NSStoryboard instantiateControllerWithIdentifier:] + 236
    16  AppKit                              0x00007fff551d0ecf NSApplicationMain + 729
    17  ACTest                              0x000000010000497d main + 13
    18  libdyld.dylib                       0x00007fff7f53d115 start + 1
    19  ???                                 0x0000000000000003 0x0 + 3
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)  

我不清楚从这里到哪里去。任何帮助表示赞赏。

【问题讨论】:

  • 将表格视图的排序描述符绑定到数组控制器的sortDescriptors。还要对 ViewController 中的数组进行排序吗?
  • 将 NSTableView 的排序描述符绑定到数组控制器似乎还不够,并在视图加载时导致 unrecognized selector sent to instance 错误。从您的消息中不清楚如何将其定向到阵列控制器的sortDescriptors。模型键路径不这样做(导致另一个错误)。
  • 不……我不需要从 ViewController 中对数组进行排序。
  • 哪个选择器不能被哪个对象/类识别?如果您不想从 ViewController 对数组进行排序,则不需要任何代码。绑定将数组控制器的sortDescriptors 设置为表格视图的sortDescriptors,数组控制器将自动对数据进行排序。列的排序键用于创建NSSortDescriptorname是正确的。
  • 2018-04-15 17:45:13.354272-0400 ACTest[48227:16210514] -[ACTest.Foo key]: unrecognized selector sent to instance 0x61000026c900 数组控制器连接到视图控制器类中的@objc dynamic var fooList : [Foo] = [...]

标签: swift4 nstableview xcode9


【解决方案1】:

这是 Cocoa Bindings 的一个经典问题:当它起作用时,它就像魔法一样,但当它不起作用时,你不知道如何解决它。我假设您已经填充了表格内容,所以我不会触及这一点。以下是处理排序的方法:

对于表格视图:

将表格视图的排序描述符绑定到数组控制器的sortDescriptors

对于表格列:

为 Name 列设置 Sort Key = name,为 Color 列设置 Sort Key = colour。不需要额外的绑定。一切就绪!

【讨论】:

  • 谢谢!这解决了我的测试应用程序和我一直试图解决的真实应用程序中的问题。知道实际记录在哪里吗?如果没有您的帮助,我不知道如何找到添加到“控制器密钥”的内容。最终,我将希望对添加/删除按钮的选择索引做类似的事情,知道在哪里看会很好。
  • 我从经验和一些尝试和错误中得到了这个工作。坦率地说,我不知道是否有任何文档。你可以试试Cocoa Bindings Programming Topics
  • 是的,这就是我一直在寻找的地方。到目前为止,我还没有在该文档中看到自 2014 年以来更新的任何内容。其中很多可以追溯到 2012 年。这些都不适用于 Swift 或最近的 Xcode 更新。不过还是谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-28
相关资源
最近更新 更多