StoryboardまたはコードでUITableViewを扱う

Storyboardでのやり方と、コードで生成するやり方をまとめてみます
`UITableViewController`には触れてないです

## Storyboardで

* `UITableView`を配置して、outlet接続します
* `UITableViewCell`を配置して、識別子をつけます
* `UITableViewCell`のスタイルを設定します
<br>`custom`にする場合は、`UITableViewCell`を継承したカスタムクラスを作る必要があります
<br>そして`UITableViewCell`に必要なものを配置します
* `datasource`を用意して、セルを生成します（下は簡単な例）

```swift
class ViewController: UIViewController {
    
    @IBOutlet weak var myTableView: UITableView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        myTableView.dataSource = self
    }
}

extension ViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 10
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = myTableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
        cell.textLabel?.text = "\(indexPath.row)"
        return cell
    }
}
```

## コードのみで

* `ViewController`に`UITableView`を追加します

```swift
class ViewController: UIViewController {
    var myTableView = UITableView()

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // myTableViewのサイズ設定は必須。frameプロパティで設定しても、autoLayoutで設定しても良い
        self.view.addSubview(myTableView)
    }
    
    // myTableViewのサイズをautoLayoutで設定する
    override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()
        myTableView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            myTableView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 0),
            myTableView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: 0),
            myTableView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 0),
            myTableView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: 0)
        ])
    }
}
```

* セル用の識別子を登録します
<br>`custom`にする場合は、`UITableViewCell`を継承したカスタムクラスを作る必要があります
<br>そして`UITableViewCell.self`を`カスタムクラス.self`に変えます

```swift
    override func viewDidLoad() {
        // 省略
        myTableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
        // 省略
    }
```

* `datasource`を用意して、セルを生成します

```swift
class ViewController: UIViewController {
    
    var myTableView = UITableView()
    
    override func viewDidLoad() {
        // 省略
        myTableView.dataSource = self
    }

    // myTableViewのサイズをautoLayoutで設定する
    override func viewWillLayoutSubviews() {
        // 省略
    }
}

// 以下のコードはStoryboardの時と同じ
extension ViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 10
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = myTableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
        cell.textLabel?.text = "\(indexPath.row)"
        return cell
    }
}
```

## xibファイルを使う

xibファイルを使う場合、カスタムセルを利用しなければならないです

`File > New > File...`または`command N`で新しいセル用のクラスを作ります
![スクリーンショット 2020-09-15 23.46.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594064/89d36721-8de8-c6e6-c377-c05c55376d9b.png)
xibファイルも一緒に作るのでチェックを入れます
![スクリーンショット 2020-09-15 23.46.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594064/82580f78-e4e2-6b19-c80d-8adf7d0a08b0.png)

xibにはこのように３つのラベルを配置します
![スクリーンショット 2020-09-15 23.52.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594064/306ad31d-9775-6605-723f-57b8c39c64af.png)

xibファイル内のViewのclass欄にカスタムセルのクラスを指定します。(自動生成の場合は自動で指定してくれます)
![スクリーンショット 2020-09-15 23.53.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594064/460bc743-cad0-928c-6680-01b490513611.png)

xibファイルのViewに配置したものを、カスタムセルのクラスにoutlet接続します
![スクリーンショット 2020-09-15 23.57.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594064/71144614-23dc-9548-2cb8-341be837741a.png)

あとは上のコードのみの時のコードを少し変えれば動きます

```swift
class ViewController: UIViewController {
    
    var myTableView = UITableView()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // myTableViewのサイズ設定は必須。frameで設定しても、autoLayoutで設定しても良い
        self.view.addSubview(myTableView)
        
        // myTableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
        myTableView.register(UINib(nibName: "myCustomCell", bundle: nil), forCellReuseIdentifier: "xibCell")
        myTableView.dataSource = self
    }
    
    // myTableViewのサイズをautoLayoutで設定する
    override func viewWillLayoutSubviews() {
        // 省略
    }


}

extension ViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 10
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        // let cell = myTableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
        // cell.textLabel?.text = "\(indexPath.row)"
        let cell = myTableView.dequeueReusableCell(withIdentifier: "xibCell", for: indexPath) as! myCustomCell
        cell.leftLabel.text = "\(indexPath.row)"
        cell.centerLabel.text = "\(indexPath.row)"
        cell.rightLabel.text = "\(indexPath.row)"
        return cell
    }
}
```

## 最後に

Storyboardとxibファイルを使わず、
完全にコードで`UITableView`とカスタムセルを実装する場合は、
コードの記述量がたくさん増えるのがわかると思います。
特にAutoLayoutをコードで書けば非常に長くなります。
どう使い分けるべきかよくわからないですが、
もしコメントで教えていただければ幸いです。

## 参考記事

[コードのみでTableViewを設置する！](https://first-code.hatenablog.com/entry/2019/09/22/095301)
[.xibを用いたUITableViewCellの実装方法](https://qiita.com/ostk0069/items/8bd4173ff4f083e35951)