Обертывание NSTableView с помощью Swift UI: как использовать привязки? - PullRequest
0 голосов
/ 02 августа 2020

Мне сложно управлять данными, которые я хочу передать в оболочку NSTableView View с помощью SwiftUI. Я пытался использовать NSViewControllerRepresentable, но проблема в том, что моя информация не обновляется должным образом.

У меня огромный список (сотни тысяч элементов) ObservableObject:

class FileObject: ObservableObject, Identifiable {
    var id : String
    @Published var line : String
    
    init(id : String, line : String) {
        self.id = id
        self.line = line
    }
}

Вот как я вызываю свой NSViewControllerRepresentable внутри SwiftUI:

struct NSLinesList: View {
    @Binding var lines: [FileObject]
    
    var body: some View {
        LinesListTableRepresentable(objects: self.$lines)
    }
}

И это реализация NSViewController, который содержит представление таблицы.

У меня есть сделал Coordinator источником данных и делегатом tableView, который находится внутри NSViewController.

private let kColumnIDContentId = "number"
private let kColumnIdContent = "content"


struct LinesListTableRepresentable: NSViewControllerRepresentable {
    typealias NSViewControllerType = LinesListViewController
    @Binding var objects : [FileObject]
    

    func makeCoordinator() -> Coordinator {
        return Coordinator(self)
    }

    func makeNSViewController(context: Context) -> LinesListViewController {
        let storyboard = NSStoryboard.init(name: .init("Main"), bundle: nil)
        let controller = storyboard.instantiateController(withIdentifier: "LinesListViewController") as! LinesListViewController
        return controller
    }

    func updateNSViewController(_ nsViewController: NSViewControllerType, context: Context) {
        nsViewController.tableView.dataSource = context.coordinator
        nsViewController.tableView.delegate = context.coordinator
    
        log.info("update the table view with \(self.objects.count) items")
        nsViewController.refresh()
    }
}

extension LinesListTableRepresentable {
    class Coordinator : NSObject, NSTableViewDelegate, NSTableViewDataSource {
        private let parent: LinesListTableRepresentable

        
        init(_ representable : LinesListTableRepresentable) {
            parent = representable
            super.init()
        }


        @objc public func numberOfRows(in tableView: NSTableView) -> Int {
            log.info("current object count inside table view: \(self.parent.objects.count)")
            return self.parent.objects.count
        }

        @objc func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {

            guard let columnId = tableColumn?.identifier else { return nil }
            let currentLine = self.parent.objects[row]

            switch columnId {
            case .init(kColumnIDContentId):
                let tableCellView = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "lineNumbercell"), owner: self) as! LogNumberTableCell
                tableCellView.contentField.stringValue = "\(row)"
                tableCellView.wantsLayer = true
                return tableCellView
            case .init(kColumnIdContent):
                let tableCellView = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "lineContentCell"), owner: self) as! LogContentTableCell
                tableCellView.contentField.stringValue = currentLine.line
            default:
                break
            }

            return nil
        }
    }
}

Я помещаю некоторые объекты внутри objects, и хотя LinesListTableRepresentable получает objects обновлено, Coordinator всегда содержит 0 элементов!

Мой вывод на консоль следующий:

2020-08-02T15:56:21+0300 info: update the table view with 2275 items
2020-08-02T15:56:21+0300 info: current object count inside table view: 0

Таким образом, кажется, что self.parent.objects.count всегда равен нулю.

Может кто с этим поможет?

...