Table View

xib-based

Drag NSTableView control to xib interface from control libraries, change control custom class to component class name of your exported.

Unlike other controls, there are several initialization and configuration methods in the controller's viewDidLoad method. The detailed code is as follows:

import Cocoa
                                
class ViewController: NSViewController {
    
    @IBOutlet weak var tableView: HDTableView!

    var verticalLineColor: NSColor?
    var horizontalLineColor: NSColor?
    
    var headBKColor: NSColor?
    var headBKGradient: NSGradient?
    var headSeparatorLineColor: NSColor?
    
    var headTitleColor: NSColor?
    var headTitleFont: NSFont?
    var headTitleAlignment: NSTextAlignment?
    var headTitleLineBreakMode: NSLineBreakMode?
    
    var cellTextColor: NSColor?
    var cellFont: NSFont? = NSFont.systemFont(ofSize: 11)
    var cellAlignment: NSTextAlignment = .left
    
    var cellFirstColor: NSColor?
    var cellFirstGradient: NSGradient?
    
    var cellSecondColor: NSColor?
    var cellSecondGradient: NSGradient?
    
    var cellHighlightColor: NSColor?
    var cellHighlightGradient: NSGradient?
    
    var columnNames:[String] = ["Table","View","Welcome"] {
        didSet {
            tableViewColumnConfig()
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        //init tableview style
        tableViewStyleConfig()
        //set tableview delegate & dataSource
        tableViewDelegateConfig()
        //init tableview columns
        tableViewColumnConfig()
    }
    
    
    func tableViewStyleConfig() {
        self.tableView.fillGradient = NSGradient.gradient(colorsStr: "rgba(130,0,233,1.0)-rgba(206,0,253,1.0)", locationsStr: "0.0-1.0")
        self.verticalLineColor = NSColor(calibratedRed: 0.38, green: 0.01, blue: 1.00, alpha: 1.0)
        self.horizontalLineColor = NSColor(calibratedRed: 0.00, green: 0.35, blue: 0.81, alpha: 1.0)
        self.headBKColor = NSColor(calibratedRed: 0.31, green: 0.16, blue: 0.68, alpha: 1.0)
        self.headTitleColor = NSColor(calibratedRed: 1.00, green: 1.00, blue: 1.00, alpha: 1.0)
        self.headTitleAlignment = .center
        self.headTitleLineBreakMode = .byTruncatingMiddle
        
        cellTextColor = NSColor(calibratedRed: 0.92, green: 0.92, blue: 0.92, alpha: 1.0)
        self.cellFont = NSFont.systemFont(ofSize: 11.0)
        self.cellAlignment = .center
        self.cellFirstColor = NSColor(calibratedRed: 0.20, green: 0.54, blue: 0.96, alpha: 1.0)
        self.cellSecondColor = NSColor(calibratedRed: 0.00, green: 0.31, blue: 0.38, alpha: 1.0)
        self.cellHighlightColor = NSColor(calibratedRed: 0.88, green: 0.00, blue: 0.31, alpha: 1.0)
    }
    
    func tableViewDelegateConfig() {
        self.tableView.delegate = self
        self.tableView.dataSource = self
    }
    
    func tableViewColumnConfig() {
        let tableColumns = tableView.tableColumns
        for tableColumn in tableColumns {
            tableView.removeTableColumn(tableColumn)
        }
        tableView.gridStyleMask = [.solidHorizontalGridLineMask , .solidVerticalGridLineMask]
        var i: Int = 0
        for columnName in columnNames {
            let column = NSTableColumn()
            let colIdentifier = NSUserInterfaceItemIdentifier(rawValue: columnName)
            column.identifier = colIdentifier
            column.width      = 60
            column.minWidth   = 40
            column.maxWidth   = 1000
            column.isEditable = true
            
            let cell = headerCell(for: columnName)
            
            column.headerCell  = cell
            tableView.addTableColumn(column)
            i += 1
        }
    }
    
    
    func headerCell(for title: String)-> HDTableHeaderCell {
        
        let cell = HDTableHeaderCell(textCell: title)
        
        let textStyle = NSMutableParagraphStyle()
        if let alignment = self.headTitleAlignment {
            textStyle.alignment     = alignment
        }
        else {
            textStyle.alignment     = .center
        }
        
        if let lineBreakMode = self.headTitleLineBreakMode {
            textStyle.lineBreakMode     = lineBreakMode
        }
        else {
            textStyle.lineBreakMode     = .byTruncatingMiddle
        }
        
        cell.gradient           = headBKGradient
        cell.backgroundColor    = headBKColor
        cell.separatorLineColor = headSeparatorLineColor
        
        var titleFont: NSFont
        if let font = headTitleFont {
            titleFont = font
        }
        else {
            titleFont = NSFont.systemFont(ofSize: 12)
        }
        
        var titleColor: NSColor
        if let color = headTitleColor {
            titleColor = color
        }
        else {
            titleColor = NSColor.textColor
        }
        
        cell.attributedStringValue = NSAttributedString(string: title, attributes: [
            NSAttributedString.Key.font: titleFont ,
            NSAttributedString.Key.foregroundColor: titleColor,NSAttributedString.Key.paragraphStyle: textStyle
            ])
        cell.isLastCell = false
        return cell
    }
}


extension ViewController: NSTableViewDelegate,NSTableViewDataSource {
    
    func numberOfRows(in tableView: NSTableView) -> Int {
        return 20
    }
    
    public func tableView(_ tableView: NSTableView, shouldEdit tableColumn: NSTableColumn?, row: Int) -> Bool {
        return false
    }
    
    func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
        
        let cell = headerCell(for:(tableColumn?.title)!)
        
        tableColumn?.headerCell = cell
        
        let text = "Cell" + "\(row)"
       
        let key = (tableColumn?.identifier)!
        
        var view = tableView.makeView(withIdentifier: key, owner: self)
        
        var  textField: NSTextField?
        if view == nil {
            textField = NSTextField()
            textField?.drawsBackground = false
            textField?.isBezeled = false
            textField?.alignment = .center
            textField?.textColor = NSColor.textColor
            textField?.font = NSFont.systemFont(ofSize: 11)
            textField?.identifier = identifier
            view = textField
        }
        else{
            textField = view as? NSTextField
        }
        
        if let cellTextColor = cellTextColor {
            textField?.textColor = cellTextColor
        }
        if let cellFont = cellFont {
            textField?.font = cellFont
        }
        textField?.alignment = cellAlignment
        
        textField?.isEditable = true
        textField?.stringValue = text
        return view
    }
    
    
    func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat {
        return 24
    }
    
    func tableView(_ tableView: NSTableView, rowViewForRow row: Int) -> NSTableRowView? {
        
        var identifierStr: String
        if (row % 2 == 0) {
            identifierStr = "DarkCell"
        } else {
            identifierStr = "LightCell"
        }
        
        let identifier = NSUserInterfaceItemIdentifier(rawValue: identifierStr)
        
        var rowView = tableView.makeView(withIdentifier:identifier, owner: nil) as? HDTableRowView
        
        if  rowView == nil {
            if row % 2 == 0 {
                rowView = HDDarkTableRowView()
            }
            else {
                rowView = HDLightTableRowView()
            }
            rowView?.identifier = identifier
        }
        
        if row % 2 == 0 {
            rowView?.fillColor = cellFirstColor
            rowView?.gradient  = cellFirstGradient
        }
        else {
            rowView?.fillColor = cellSecondColor
            rowView?.gradient  = cellSecondGradient
        }
        
        rowView?.highlightColor    = cellHighlightColor
        rowView?.highlightGradient = cellHighlightGradient
        rowView?.horizontalLineColor = horizontalLineColor
        
        return rowView
    }
    
}


code-based

Declare lazy load variable tableView and scrollView in the controller class , add scrollView to the view. implement several initialization and configuration methods in the controller's viewDidLoad method. The detailed code is as follows:

import Cocoa
class ViewController: NSViewController {

    lazy var scrollView: NSScrollView = {
        let scrollView = NSScrollView()
        scrollView.focusRingType = .none
        scrollView.autohidesScrollers = true
        scrollView.borderType = .noBorder
        scrollView.documentView = self.tableView
        scrollView.translatesAutoresizingMaskIntoConstraints = false
        return scrollView
    }()
    
    lazy var tableView: HDTableView = {
        let tableView = HDTableView()
        tableView.focusRingType = .none
        tableView.delegate = self
        tableView.dataSource = self
        return tableView
    }()
    
    var fillColor: NSColor?
    var fillGradient: NSGradient?
    
    var header: NSTableHeaderView?
    var hasHeader: Bool = true {
        didSet {
            if self.tableView.headerView != nil {
                header =  self.tableView.headerView
            }
            if hasHeader {
                if let header = header {
                    self.tableView.headerView = header
                    self.tableView.reloadData()
                }
            }
            else {
                self.tableView.headerView = nil
            }
        }
    }
    
    var verticalLineColor: NSColor?
    var horizontalLineColor: NSColor?
    
    var headBKColor: NSColor?
    var headBKGradient: NSGradient?
    var headSeparatorLineColor: NSColor?
    
    var headTitleColor: NSColor?
    var headTitleFont: NSFont?
    var headTitleAlignment: NSTextAlignment?
    var headTitleLineBreakMode: NSLineBreakMode?
    
    var cellTextColor: NSColor?
    var cellFont: NSFont? = NSFont.systemFont(ofSize: 11)
    var cellAlignment: NSTextAlignment = .left
    
    var cellFirstColor: NSColor?
    var cellFirstGradient: NSGradient?
    
    var cellSecondColor: NSColor?
    var cellSecondGradient: NSGradient?
    
    var cellHighlightColor: NSColor?
    var cellHighlightGradient: NSGradient?
    
    var columnNames:[String] = ["Table","View"] {
        didSet {
            tableViewColumnConfig()
        }
    }
   
    override func viewDidLoad() {
        super.viewDidLoad()
        //init tableview style
        tableViewStyleConfig()
        //add tableview to view
        addTabView()
        //set autolayout
        setupAutolayout()
        //set tableview delegate & dataSource
        tableViewDelegateConfig()
        //config tableView columns
        tableViewColumnConfig()
    }
    
    func addTabView() {
        self.view.addSubview(scrollView)
    }
    
    func setupAutolayout() {
        scrollView.left = 10
        scrollView.right = -10
        scrollView.top = 10
        scrollView.bottom = -10
    }
    
    func tableViewStyleConfig() {
        self.hasHeader = true
        self.headBKColor = NSColor(calibratedRed: 1.00, green: 1.00, blue: 1.00, alpha: 1.0)
        self.headTitleColor = NSColor(calibratedRed: 0.42, green: 0.42, blue: 0.42, alpha: 1.0)
        self.headTitleAlignment = .center
        self.headTitleLineBreakMode = .byTruncatingMiddle
        
        cellTextColor = NSColor(calibratedRed: 0.42, green: 0.42, blue: 0.42, alpha: 1.0)
        self.cellFont = NSFont.systemFont(ofSize: 11.0)
        self.cellFirstColor = NSColor(calibratedRed: 0.95, green: 0.95, blue: 0.95, alpha: 1.0)
        self.cellSecondColor = NSColor(calibratedRed: 1.00, green: 1.00, blue: 1.00, alpha: 1.0)
        self.cellHighlightColor = NSColor(calibratedRed: 0.02, green: 0.25, blue: 0.76, alpha: 1.0)
    }
    
    func tableViewDelegateConfig() {
        self.tableView.focusRingType = .none
        self.tableView.delegate = self
        self.tableView.dataSource = self
    }
    
    func tableViewColumnConfig() {
        let tableColumns = tableView.tableColumns
        for tableColumn in tableColumns {
            tableView.removeTableColumn(tableColumn)
        }
        tableView.gridStyleMask = [.solidHorizontalGridLineMask , .solidVerticalGridLineMask]
        var i: Int = 0
        for columnName in columnNames {
            let column = NSTableColumn()
            let colIdentifier = NSUserInterfaceItemIdentifier(rawValue: columnName)
            column.identifier = colIdentifier
            column.width      = 60
            column.minWidth   = 40
            column.maxWidth   = 1000
            column.isEditable = true
            
            let cell = headerCell(for: columnName)
            
            column.headerCell  = cell
            tableView.addTableColumn(column)
            i += 1
        }
    }
    
    func headerCell(for title: String) -> HDTableHeaderCell {
        
        let cell = HDTableHeaderCell(textCell: title)
        
        let textStyle = NSMutableParagraphStyle()
        if let alignment = self.headTitleAlignment {
            textStyle.alignment     = alignment
        }
        else {
            textStyle.alignment     = .center
        }
        
        if let lineBreakMode = self.headTitleLineBreakMode {
            textStyle.lineBreakMode     = lineBreakMode
        }
        else {
            textStyle.lineBreakMode     = .byTruncatingMiddle
        }
        
        cell.gradient           = headBKGradient
        cell.backgroundColor    = headBKColor
        cell.separatorLineColor = headSeparatorLineColor
        
        var titleFont: NSFont
        if let font = headTitleFont {
            titleFont = font
        }
        else {
            titleFont = NSFont.systemFont(ofSize: 12)
        }
        
        var titleColor: NSColor
        if let color = headTitleColor {
            titleColor = color
        }
        else {
            titleColor = NSColor.textColor
        }
        
        cell.attributedStringValue = NSAttributedString(string: title, attributes: [
        NSAttributedString.Key.font: titleFont ,
        NSAttributedString.Key.foregroundColor: titleColor,NSAttributedString.Key.paragraphStyle: textStyle
        ])
        cell.isLastCell = false
        return cell
    }
}

extension ViewController: NSTableViewDelegate,NSTableViewDataSource {
    
    func numberOfRows(in tableView: NSTableView) -> Int {
        return 20
    }
    
    public func tableView(_ tableView: NSTableView, shouldEdit tableColumn: NSTableColumn?, row: Int) -> Bool {
        return false
    }
    
    func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
        
        let cell = headerCell(for:(tableColumn?.title)!)
        tableColumn?.headerCell = cell
        let text = "Cell" + "\(row)"
        let key = (tableColumn?.identifier)!
        var view = tableView.makeView(withIdentifier: key, owner: self)
        
        var  textField: NSTextField?
        if view == nil {
            textField = NSTextField()
            textField?.drawsBackground = false
            textField?.isBezeled = false
            textField?.alignment = .center
            textField?.textColor = NSColor.textColor
            textField?.font = NSFont.systemFont(ofSize: 11)
            textField?.identifier = identifier
            view = textField
        }
        else{
            textField = view as? NSTextField
        }
        if let cellTextColor = cellTextColor {
            textField?.textColor = cellTextColor
        }
        if let cellFont = cellFont {
            textField?.font = cellFont
        }
        textField?.alignment = cellAlignment
        
        textField?.isEditable = true
        textField?.stringValue = text
        return view
    }
    
    func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat {
        return 24
    }
    
    func tableView(_ tableView: NSTableView, rowViewForRow row: Int) -> NSTableRowView? {
        
        var identifierStr: String
        if (row % 2 == 0) {
            identifierStr = "DarkCell"
        } else {
            identifierStr = "LightCell"
        }
        let identifier = NSUserInterfaceItemIdentifier(rawValue: identifierStr)
        var rowView = tableView.makeView(withIdentifier:identifier, owner: nil) as? HDTableRowView
        
        if  rowView == nil {
            if row % 2 == 0 {
                rowView = HDDarkTableRowView()
            }
            else {
                rowView = HDLightTableRowView()
            }
            rowView?.identifier = identifier
        }
        if row % 2 == 0 {
            rowView?.fillColor = cellFirstColor
            rowView?.gradient  = cellFirstGradient
        }
        else {
            rowView?.fillColor = cellSecondColor
            rowView?.gradient  = cellSecondGradient
        }
        
        rowView?.highlightColor    = cellHighlightColor
        rowView?.highlightGradient = cellHighlightGradient
        rowView?.horizontalLineColor = horizontalLineColor
        
        return rowView
    }
}