8

Has anyone gotten NSTableView to work with SwiftUI? Whenever I run my code my app will not load but there are also no errors. There aren't any examples for tableviews but I thought it would be using the NSViewControllerRepresentable. I'm not entirely sure how you style the table and add it to the view. Thank you for the help!

struct SampleViewController: NSViewControllerRepresentable {
    
    var tableView:NSTableView = {
        let table = NSTableView(frame: .zero)
        table.rowSizeStyle = .large
        table.backgroundColor = .clear
        return table
    }()
    
    func makeNSViewController(context: Context) -> NSViewController {
        
        return NSViewController()
    }
    
    func updateNSViewController(_ nsViewController: NSViewController, context: Context) {
        //tbd
    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }
    
    class Coordinator: NSObject, NSTableViewDataSource, NSTableViewDelegate {
        var parent: SampleViewController
        
        init(_ tvController: SampleViewController) {
            self.parent = tvController
        }
        
        func numberOfRows(in tableView: NSTableView) -> Int {
            return 10
        }
        
        func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
            return nil
        }
        
        func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat {
            return CGFloat(90)
        }
        
        func tableView(_ tableView: NSTableView, shouldSelectRow row: Int) -> Bool {
            return false
        }

    }

    
}


struct SampleView: View {
    var body: some View {
        SampleViewController()
    }
}
Clay Bridges
  • 11,602
  • 10
  • 68
  • 118
lostAstronaut
  • 1,331
  • 5
  • 20
  • 34
  • Have you tried NSViewRepresentable? I did not try either of those, but I would start from this one. – Asperi Nov 26 '19 at 18:13
  • I had tried NSViewRepresentable first, in apple's example (https://developer.apple.com/tutorials/swiftui/interfacing-with-uikit) they used controller representable to control the pages. I thought that would be closest since they also had to implement delegate methods – lostAstronaut Nov 26 '19 at 18:20
  • There was `UIPageViewController` there, but `NSTableView` is view. So what's the goal? It is possible, but to make it full-functional it needs a lot of manual work. Thus it is better to prepare needed custom controller in storyboard which will manage everything needed, and then just wrap it in `UIViewControllerRepresentable`. – Asperi Nov 26 '19 at 18:36
  • You need to make a MacOS app with table first. Then you can be familiar with transferring to swiftUI. The second part is not hard. But the first part is different as the NSTableView has different behavior from UITableView. – E.Coms Nov 26 '19 at 18:44
  • @Asperi the goal is to have a fully functioning TableView similar to what i'd have in storyboard. I can make it in storyboard fine but wanted to see if I could remove some storyboard formatting and move it to SwiftUI. So you'd recommend creating the ViewController in storyboard and have all the above coordinator functions in a ViewController class, then wrap all of that in NSViewControllerRepresentable to use throughout the app? – lostAstronaut Nov 26 '19 at 18:52
  • @E.Coms my goal was to see if I could migrate some storyboard views to SwiftUI but it seems the api is not as developed as i'd like – lostAstronaut Nov 26 '19 at 18:53
  • Yes, I meant that. – Asperi Nov 26 '19 at 18:54

1 Answers1

1

I have a feeling you might have figured this one out, but you haven't actually set the tableView property as the view of your view controller. So, when presented, your SwiftUI view is just going to be backed by a plain NSView.

In this particular example, I think an NSViewRepresentable would probably be nicer, since your controller has no logic anyways.

Just in case this is helpful, another thing to keep in mind is the role of the coordinator and its relationship to the parent property. Because the coordinator is created and reused, its parent is not updated if the SwiftUI view is re-created. This really tripped me up as I tried to reload table data in func updateNSViewController(_ nsViewController: NSViewController, context: Context)

Mattie
  • 2,868
  • 2
  • 25
  • 40