SwiftUI 集成 NSTableView

SwiftUI 写起页面来是比较方便, 但是缺少表格组件, 官方只提供了List, Grid 用来扩展, 简单表格没有问题, 涉及到复杂一点的表格, 就基本无解了, 不过xcode13开始提供了Table组件, 支持情况有点不乐观了 “macOS 12.0+”, NSTableView 已经比较完善了, 只能先引入过渡了

  1. 创建controller(我的名称叫ClientListTableController.swift)
    image.png

  2. 创建对应的View视图(我的名称叫ClientListTableController.xib)
    image.png

  3. 打开视图(ClientListTableController.xib),添加NSTableView
    image.png

  4. 设置表格列title, 和绑定的数据名称, 根据自己业务设置其它列
    image.png

    image.png

  5. 在视图(ClientListTableController.xib)里添加ArrayController(处理表格数据)

    image.png

  6. 指定视图(ClientListTableController.xib)的controller

    image.png

  7. 连线View, Controller

    image.png

    import Cocoa
    
    class ClientListTableController: NSViewController {
        @IBOutlet weak var tableView: NSTableView!
    
        override func viewDidLoad() {
            super.viewDidLoad()
        }
    }
    复制代码
  8. 连线arrayController

    image.png

    import Cocoa
    
    class ClientListTableController: NSViewController {
        @IBOutlet weak var tableView: NSTableView!
        @IBOutlet var arrayController: NSArrayController!
    
        override func viewDidLoad() {
            super.viewDidLoad()
        }
    }
    复制代码
  9. 指定view
    image.png

  10. 指定arrayController 绑定值
    image.png

  11. 绑定TableView content 到 arrayController
    image.png

  12. 创建SwiftUI view文件(ClientListDemo.swift), 用来预览表格
    image.png

代码如下:


import Foundation

class ClientModel:NSObject, Identifiable {
    @objc var id:Int = 0
    @objc var name:String = UUID().uuidString
}
复制代码
import Cocoa

class ClientListTableController: NSViewController {
    @objc dynamic var list: [ClientModel] = []
    
    @IBOutlet weak var tableView: NSTableView!
    @IBOutlet var arrayController: NSArrayController!
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    func setList(_ list:[ClientModel]) -> Void {
        self.list = list
    }
}
复制代码

import SwiftUI
import Cocoa

struct ClientListDemo: View {
    var body: some View {
        Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/)
    }
}

struct ClientListDemo_Previews: PreviewProvider {
    
    @State static var list = [ClientModel](repeating: ClientModel(), count: 4)
    @State static var selectRowIndex: Int = -1
    
    static var previews: some View {
        ClientTable(list: $list, selectRowIndex: $selectRowIndex)
    }
}




struct ClientTable: NSViewControllerRepresentable {
    @Binding var list: [ClientModel]
    @Binding var selectRowIndex: Int
    
    func makeCoordinator() -> Coordinator {
        return Coordinator(self)
    }
    
    
    func makeNSViewController(context: Context) -> NSViewController {
        let controller = ClientListTableController()
        return controller
    }
    
    
    func updateNSViewController(_ nsViewController: NSViewController, context: Context) {
        guard let controller = nsViewController as? ClientListTableController else {return}
        controller.setList(list)
        controller.tableView?.delegate = context.coordinator
    }
    
    class Coordinator: NSObject, NSTableViewDelegate {
        
        var table: ClientTable
        
        init(_ table: ClientTable) {
            self.table = table
        }
        
        func tableViewSelectionDidChange(_ notification: Notification) {
            guard let tableView = notification.object as? NSTableView else {return}
            guard self.table.list.count > 0 else {return}
            guard tableView.selectedRow >= 0 else {
                self.table.selectRowIndex = -1
                return
            }
            self.table.selectRowIndex = tableView.selectedRow
        }
        
    }
}
复制代码

可以正常显示了

image.png

在我的工具中有使用到这块代码, 详见:redis-pro

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享