NSTableView - How do I remove the horizontal gap between table cells

I am creating my own NSTableView for macOS. I can display formatted data and provide scrolling by embedding it in a ScrollView. When the table is displayed there is a horizontal gap between adjacent cells. The same gap occurs between the ScrollView header cells. I do not know how to. solve this problem. There is one other issue, I do not know how to set the vertical height of the ScrollView header cells. I would like to make them taller. Below is my code along with the test data.

struct ClosingValue: Identifiable {
    var id: UUID
    var name: String
    var date: String
    var close: Float
    
    static var closingValues = [
        ClosingValue(id: UUID(), name: "Stock1", date: "Nov 01, 2009", close: 1.10),
        ClosingValue(id: UUID(), name: "Stock1", date: "Nov 02, 2009", close: 2.10),
        ClosingValue(id: UUID(), name: "Stock1", date: "Nov 03, 2009", close: 3.10),
        ClosingValue(id: UUID(), name: "Stock1", date: "Nov 04, 2009", close: 4.10),
        ClosingValue(id: UUID(), name: "Stock1", date: "Nov 05, 2009", close: 5.10)
    ]
}

struct BetterTableView: NSViewRepresentable {
    
    class Coordinator: NSObject, NSTableViewDelegate, NSTableViewDataSource {
        
        @State var closingValues: [ClosingValue] = ClosingValue.closingValues
        
        func numberOfRows(in tableView: NSTableView) -> Int {
            closingValues.count
        }
        
        func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
            
            var nsView = NSView()
            let tableColumnWidth: CGFloat = 135
            
            let paragraphStyle = NSMutableParagraphStyle()
            paragraphStyle.alignment = .center
            
            let attributes1: [NSAttributedString.Key: Any] = [
                .foregroundColor: NSColor.blue,
                .paragraphStyle: paragraphStyle,
                .font: NSFont(name: "Arial", size: 14.0) as Any
            ]
            
            switch tableColumn {
                
            case tableView.tableColumns[0]:
                tableColumn?.width = tableColumnWidth
                let attributedString = NSAttributedString(string: closingValues[row].name, attributes: attributes1)
                
                let tempNSView = NSTextField()
                tempNSView.backgroundColor = NSColor.white
                tempNSView.isBordered = true
                tempNSView.isEditable = false
                tempNSView.attributedStringValue = attributedString
                
                nsView = tempNSView
            case tableView.tableColumns[1]:
                tableColumn?.width = tableColumnWidth
                let attributedString = NSAttributedString(string: closingValues[row].date, attributes: attributes1)
                
                let tempNSView = NSTextField()
                tempNSView.backgroundColor = NSColor.white
                tempNSView.isBordered = true
                tempNSView.isEditable = false
                tempNSView.attributedStringValue = attributedString
                
                nsView = tempNSView
            case tableView.tableColumns[2]:
                
                tableColumn?.width = tableColumnWidth
                let closeAsString = String(format: "$%.2f", closingValues[row].close)
                let attributedString = NSAttributedString(string: closeAsString, attributes: attributes1)
                
                let tempNSView = NSTextField()
                tempNSView.backgroundColor = NSColor.white
                tempNSView.isBordered = true
                tempNSView.isEditable = false
                tempNSView.attributedStringValue = attributedString
                
                nsView = tempNSView
            default:
                print("problem in table view switch statement")
            }
            return nsView
        }
    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator()
    }
    
    func makeNSView(context: Context) -> NSScrollView {
        
        let tableView = NSTableView()
        tableView.delegate = context.coordinator
        tableView.dataSource = context.coordinator
        tableView.addTableColumn(NSTableColumn())
        tableView.addTableColumn(NSTableColumn())
        tableView.addTableColumn(NSTableColumn())
        
        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.alignment = .center
        
        let attributes: [NSAttributedString.Key: Any] = [
            .foregroundColor: NSColor.black,
            .paragraphStyle: paragraphStyle,
            .font: NSFont.systemFont(ofSize: 14)
        ]
        
        let column0AttributedString = NSAttributedString(string: "Stock", attributes: attributes)
        let column0Header = tableView.tableColumns[0]
        column0Header.headerCell.drawsBackground = true
        column0Header.headerCell.backgroundColor = NSColor.systemMint
        column0Header.headerCell.alignment = .center
        column0Header.headerCell.attributedStringValue = column0AttributedString
        
        let column1AttributedString = NSAttributedString(string: "Date", attributes: attributes)
        let column1Header = tableView.tableColumns[1]
        column1Header.headerCell.drawsBackground = true
        column1Header.headerCell.backgroundColor = NSColor.systemMint
        column1Header.headerCell.alignment = .center
        column1Header.headerCell.attributedStringValue = column1AttributedString
        
        let column2AttributedString = NSAttributedString(string: "Closing Value", attributes: attributes)
        let column2Header = tableView.tableColumns[2]
        column2Header.headerCell.drawsBackground = true
        column2Header.headerCell.backgroundColor = NSColor.systemMint
        column2Header.headerCell.alignment = .center
        column2Header.headerCell.attributedStringValue = column2AttributedString
        
        let scrollView = NSScrollView()
        scrollView.documentView = tableView

        
        return scrollView
    }
    
    func updateNSView(_ nsView: NSScrollView, context: Context) {
        let tableView = (nsView.documentView as! NSTableView)
        // work on this section
    }
}
Answered by ChrisMH in 762076022

After some additional review of the NSTableView class, I discovered it contains a var "intercellSpacing" of type NSSize. So I added the line of code below to the "makeNSView" function above and the cell spacing problem is solved. It did not though get rid of the green block to the left of "Stock" or to the right of "Closing Value". If I am able to work that out I will add the solution to this post.

tableView.intercellSpacing = NSSize(width: 0.0, height: 0.0)

Posting a screenshot could help understand precisely. May be due to the tableView width and the automatic balance of cells inside ?

My apologies.

Accepted Answer

After some additional review of the NSTableView class, I discovered it contains a var "intercellSpacing" of type NSSize. So I added the line of code below to the "makeNSView" function above and the cell spacing problem is solved. It did not though get rid of the green block to the left of "Stock" or to the right of "Closing Value". If I am able to work that out I will add the solution to this post.

tableView.intercellSpacing = NSSize(width: 0.0, height: 0.0)

I do not see how you sized both the scrollView and TableView, so that they match exactly.

Note you could streamline somehow the code:

            tableColumn?.width = tableColumnWidth
            var attributedString = NSAttributedString()  // To initialize
            var tempNSView = NSTextField()

            switch tableColumn {
                
            case tableView.tableColumns[0]:
                attributedString = NSAttributedString(string: closingValues[row].name, attributes: attributes1)
                
            case tableView.tableColumns[1]:
                attributedString = NSAttributedString(string: closingValues[row].date, attributes: attributes1)
                                
            case tableView.tableColumns[2]:
                
                let closeAsString = String(format: "$%.2f", closingValues[row].close)
                attributedString = NSAttributedString(string: closeAsString, attributes: attributes1)
                
            default:
                print("problem in table view switch statement")
                return nil // or NSView()
            }

            tempNSView.backgroundColor = NSColor.white
            tempNSView.isBordered = true
            tempNSView.isEditable = false
            tempNSView.attributedStringValue = attributedString
                
            nsView = tempNSView

To solve the final problem, the borders (green blocks) on the left and right of the table, I inserted the code "tableView.style = ..plain".

NSTableView - How do I remove the horizontal gap between table cells
 
 
Q