Macアプリ初心者：NSTableView で一覧を作ってみる


Macアプリを作るための日本語用のドキュメントが少ないので備忘録的にまとめていこうかと思います。

# 環境
* macOS Mojave：10.14.6
* Xcode：10.3

#プロジェクトを作成
今回は macOS の Cocoa App を選択
![スクリーンショット 2019-08-22 9.20.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203864/dffcf360-cfe3-dc3c-2d85-eb6d1eb4930d.png "スクリーンショット 2019-08-22 9.20.39.png")

# StoryBoard
## NSTableView を ViewController に配置
![スクリーンショット 2019-08-22 9.22.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203864/6d87119f-a641-47a1-d6e2-7329a59b95e7.png "スクリーンショット 2019-08-22 9.22.28.png")

# 適当に NSTableViewに 制約を追加
![スクリーンショット 2019-08-22 9.28.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203864/b3f4261f-62cf-ad15-47a5-73f82754ab9a.png "スクリーンショット 2019-08-22 9.28.59.png")

# NSTableViewCell の Identity -> Identifier に「MyView」を設定
![スクリーンショット 2019-08-22 13.54.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203864/75256ce1-bb5c-deb0-c39f-aa1beb551908.png "スクリーンショット 2019-08-22 13.54.49.png")

# ソースコードから NSTableView を参照
![スクリーンショット 2019-08-22 13.52.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203864/1cda6a8c-de5f-2684-79dd-a5552e6635dd.png "スクリーンショット 2019-08-22 13.52.43.png")


# ソースコード
## ViewController に Protocol(NSTableViewDataSource, NSTableViewDelegate) を適用
```swift:ViewController.swift
extension ViewController: NSTableViewDataSource, NSTableViewDelegate {
}
```

## StoryBoard と関連づけた NSTableView に dataSource と delegate を設定
```swift:ViewController.swift
    @IBOutlet weak var tableView: NSTableView! {
        didSet {
            self.tableView.dataSource = self
            self.tableView.delegate = self
        }
    }
```


## NSTableView で表示するデータを適当に作成
```swift:ViewController.swift
    private var values: [String] {
        var results = [String]()
        for i in 0...100 {
            results.append("append [\(i)]")
        }
        return results
    }
```

## NSTableViewDataSource, NSTableViewDelegate で最低限の関数を実装
StoryBoard で Identifier に「MyView」を設定した NSSTableViewCell を利用
```swift:ViewController.swift
extension ViewController: NSTableViewDataSource, NSTableViewDelegate {
    
    // MARK: - NSTableViewDataSource
    func numberOfRows(in tableView: NSTableView) -> Int {
        return self.values.count
    }
    
    
    // MARK: - NSTableViewDelegate
    func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
        let result = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "MyView"), owner: self) as? NSTableCellView
        
        // Set the stringValue of the cell's text field to the nameArray value at row
        result?.textField?.stringValue = self.values[row]
        
        // Return the result
        return result
    }
}
```

<details><summary>全ソースコード(ViewController)</summary><div>

```swift:ViewController.swift
import Cocoa

class ViewController: NSViewController {

    // MARK: - IBOutlet
    @IBOutlet weak var tableView: NSTableView! {
        didSet {
            self.tableView.dataSource = self
            self.tableView.delegate = self
        }
    }
    
    // MARK: - private variables
    private var values: [String] {
        var results = [String]()
        for i in 0...100 {
            results.append("append [\(i)]")
        }
        return results
    }


    // MARK: - override func
    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }

    override var representedObject: Any? {
        didSet {
        // Update the view, if already loaded.
        }
    }
}

extension ViewController: NSTableViewDataSource, NSTableViewDelegate {
    
    // MARK: - NSTableViewDataSource
    func numberOfRows(in tableView: NSTableView) -> Int {
        return self.values.count
    }
    
    
    // MARK: - NSTableViewDelegate
    func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
        let result = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "MyView"), owner: self) as? NSTableCellView
        
        // Set the stringValue of the cell's text field to the nameArray value at row
        result?.textField?.stringValue = self.values[row]
        
        // Return the result
        return result
    }
}
```

</div></details>

# 完成
![スクリーンショット 2019-08-26 9.29.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203864/dd8acb84-3233-aaef-f888-a2da05018eac.png "スクリーンショット 2019-08-26 9.29.56.png")