如何通过Interface Builder实现NSTableView列可排序
我太懂这种官方文档过时坑人的糟心感了!之前折腾NSTableView排序的时候也踩过旧文档的坑,结合你写的Foo类,给你一套适配最新Cocoa环境的靠谱步骤:
搞定NSTableView IB排序的正确姿势(适配最新Cocoa)
1. 先确认你的Foo类配置正确
你的Foo类写法方向是对的,补全一下确保没有遗漏关键配置:
class Foo: NSObject { @objc dynamic var name: String @objc dynamic var colour: String init(name: String, colour: String) { self.name = name self.colour = colour super.init() } }
这里必须加@objc dynamic,因为NSTableView的排序依赖KVC机制访问属性,少了这个排序根本触发不了。
2. Interface Builder里的关键配置(避开旧文档的坑)
这部分是旧官方文档最容易误导人的地方,按下面的步骤来:
2.1 配置Array Controller(核心!)
- 拖一个
Array Controller到你的xib/storyboard里(在Object Library搜索即可) - 选中Array Controller,在Identity Inspector里确认Class是
NSArrayController(默认就是,但保险起见检查下) - 切换到Attributes Inspector:
- 把
Mode改成Class Class Name填Foo(要和你的类名完全一致,大小写敏感)
- 把
- 切换到Bindings Inspector,找到
Content Array,绑定到你的ViewController里的数据源数组:- 比如你在ViewController里有
@objc dynamic var foos: [Foo] = [],就把Bind to设为ViewController,Model Key Path填foos
- 比如你在ViewController里有
2.2 给Table Column设置排序规则
- 选中你要加排序的Table Column(比如Name列)
- 切换到Attributes Inspector:
- 在
Sorting区域,Sort Key填对应的属性名,比如name(和Foo类里的属性名完全一致) Selector填compare:(字符串默认用这个,数字/日期也可以用compare:,自定义排序的话后面说)- ❌ 重点:别去绑定
sortDescriptorPrototype!旧文档可能让你这么做,但现在这步完全不需要,反而会出问题
- 在
2.3 启用TableView的排序功能
- 选中NSTableView,在Attributes Inspector里,找到
Sorting下的Allows Sorting,勾选它
3. 自定义排序逻辑(可选)
如果默认的compare:满足不了需求(比如colour列要按特定顺序排序),可以给Foo类加自定义的比较方法:
extension Foo { @objc func compareColour(with other: Foo) -> ComparisonResult { // 举个例子:按红、绿、蓝的优先级排序 let priorityOrder = ["Red", "Green", "Blue"] guard let selfRank = priorityOrder.firstIndex(of: colour), let otherRank = priorityOrder.firstIndex(of: other.colour) else { // 如果不在优先级列表里,就用默认字符串排序 return colour.compare(other.colour) } return selfRank.compare(otherRank) } }
然后回到IB的Colour列,把Selector改成compareColour(with:)就行。
4. 排障小技巧
如果点击表头没反应,检查这几点:
- Foo类的属性是不是都加了
@objc dynamic - Array Controller的
Class Name是不是和Foo类名完全一致 - Table Column的
Sort Key是不是和属性名完全匹配(大小写、拼写都不能错) - NSTableView的
Allows Sorting有没有勾选 - 数据源数组是不是绑定到了Array Controller的
Content Array
要是还有问题,你可以贴出IB的配置截图或者更多代码细节,我再帮你排查!
内容的提问来源于stack exchange,提问作者mpounsett
相关产品推荐
相关产品推荐

