macOS Dev: NSTableView

实现一个 NSTableView,NSTableCellVIew 根据内容量和 window 宽度自动适应高度。

NSTableView 和 UITableView 有很大不同。比如 iOS 在设置好 autolayout 之后就不用去管 cell 的高度了。但是 macOS 中仍然需要提供高度数据。其他诸如点击事件,响应 cell 的背景色等等 api 也和 iOS 不一样。由于 window 的大小可变,渲染图形的时候要考虑到这种情况,不能依赖 autolayout 一劳永逸。总之, macOS 要考虑的情况多一些,能找到的资料又相对欠缺。

NSTableView

  • Storyboard 中往 ViewController 拖入 NSTableView 控件,设置 autolayout 填满视图

  • 中栏层级结构图中右键拖放 Table View 至 View Controller,连接 NSTableViewDelegate 和 NSTableViewDataSource

  • 拖一个 tableView 的 IBOutlet 引用至 ViewController

  • 注册 Cell

      @IBOutlet weak var tableView: NSTableView!{
          didSet{
              let nib = NSNib(nibNamed: "CustomCell", bundle: nil)
              self.tableView.register(nib, forIdentifier: "CustomCell")
          }
      }
    

让 Cell 填满视图宽度

  • 选择 table view 后,Attributes inspector 中设置 Columns: 1,去掉 Headers, Reordering, Resizing 选项,Column Sizing: Uniform
  • 如果显示不正确,把 table view 拉到比两个 columns 还小的宽度,然后再拉回与 window 宽度同宽

NSTableCellView

  • 新建 CustomCell.swift
  • 新建 macOS > User Interface > Empty > CustomCell.xib,拖入 NSTableCellView,拖入一个 Custom View 作为 contentView,之后所有的空间都放在这个 contentView 上,稍后将用这个 contentView 来获得 cell 的高度
  • Attribute Inspector 中设置 CustomCell.xib 的类为 CustomCell,identifier > CustomCell,拖 IBOutlet 至 CustomCell.swift

把值显示到 cell 的两种方式

1. 绑定 Object

  • 选择 Table Cell View,Bindings inspector > value > Bind to: Table Cell View,Model Key Path: objectValue

2. 给 NSTableCellView 实例赋值

func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
    let cell = tableView.make(withIdentifier: "CustomCell", owner: self) as! CustomCell
    let item = dataSource?[row]
    cell.setContent(item: item)
    return cell
}

动态高度

通过容器视图的 fittingSize 方法获得高度

func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat {
    let cell = tableView.make(withIdentifier: "CustomCell", owner: self) as! CustomCell
    let item = dataSource?[row]
    cell.setContent(item: item)
    return cell.contentView.fittingSize.height
}

收取窗口改变的通知,在 window 大小改变的时候 reloadData()。

 NotificationCenter.default.addObserver(self, selector: #selector(receivedNotification(notification:)), name: NSNotification.Name.NSWindowDidResize, object: nil)

demo

参考

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,252评论 4 61
  • UITableViewCell 高度计算 UITableView 询问 cell 高度有两种方式:1.rowHei...
    WeiHing阅读 4,473评论 6 16
  • 现在可以理直气壮地 丢掉整个冬天去爱雨 忘乎所以 最好你在雨里没有伞 我送过去 人们嚼着咸湿的空气 幽会外遇 这个...
    傻子悲伤阅读 290评论 0 1
  • 月洒坡,已是寂夜剩蟾蜍、 蝉鸣声,柔光泻下雨露清、 绿草波,...
    祁连诗人阅读 215评论 0 2
  • 东至,反向的冬至 气温28度 据说午后将有强对流天气 冰雹肆虐,高速封堵 还有十级大风 山民说 映山红这几天开得正...
    丹崖阅读 303评论 1 0