UITableViewの一部のセクションのSeparatorを非表示にする

一部のセルや全てのセルのSeparatorを消す方法は既に色んな記事でまとめられていますが、今回は一部セクションのSeparatorのみを非表示にする方法について紹介します。

## Environment
- Xcode10.2
- Swift5


## Source
e.g. セクション数が2つ、`section.row == 0`の場合のみSeparatorを削除することとします。

```ViewController.swift
import UIKit

class ViewController: UIViewController {
    private enum Const {
        static let sections = ["section0", "section1"]
        static let rowNumber = 50
    }

    private let tableView: UITableView = {
        let tableView = UITableView(frame: .zero, style: .grouped)
        tableView.translatesAutoresizingMaskIntoConstraints = false
        tableView.register(UINib(nibName: CustomCell.className, bundle: nil), forCellReuseIdentifier: CustomCell.className)
        return tableView
    }()

    override func viewDidLoad() {
        tableView.dataSource = self
        view.addSubview(tableView)

        NSLayoutConstraint.activate([
            view.topAnchor.constraint(equalTo: tableView.topAnchor),
            view.bottomAnchor.constraint(equalTo: tableView.bottomAnchor),
            view.leadingAnchor.constraint(equalTo: tableView.leadingAnchor),
            view.trailingAnchor.constraint(equalTo: tableView.trailingAnchor)
            ])
    }
}

extension ViewController: UITableViewDataSource {
    func numberOfSections(in tableView: UITableView) -> Int {
        return Const.sections.count
    }

    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return Const.sections[section]
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return Const.rowNumber
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell =  tableView.dequeueReusableCell(withIdentifier: CustomCell.identifier) as! CustomCell

        // configure separator
        do {
            let hasSeparator = indexPath.section == 0
            cell.configure(hasSeparator: hasSeparator)
        }
        cell.textLabel?.text = String(indexPath.row)
        return cell
    }
}
```

```CustomCell.swift
import UIKit

extension UITableViewCell {
    static var identifier: String {
        return String(describing: self)
    }
    static var className: String {
        return String(describing: self)
    }
}

class CustomCell: UITableViewCell {
    private var hasSeparator = true

    override func layoutSubviews() {
        super.layoutSubviews()
        toggleSeparator()
    }

    func configure(hasSeparator: Bool) {
        self.hasSeparator = hasSeparator
    }

    private func toggleSeparator() {
        for separatorView in subviews where separatorView != contentView {
            separatorView.isHidden = hasSeparator
        }
    }
}
```


## GIF
以下のように`section0`のSeparatorのみ消えています。
![separator.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116582/928f6a8c-dd70-6da7-4e7d-aa5a9f85c3ea.gif)



## Point
- `func toggleSeparator`内の`isHidden`でSeparatorの表示・非表示を切り替えています。

```.swift
    private func toggleSeparator() {
        for separatorView in subviews where separatorView != contentView {
            separatorView.isHidden = hasSeparator
        }
    }
```
- `func toggleSeparator`内で`isHidden`ではなく、`removeFromSuperView`を使用する場合、セルの再利用時に表示したいセクションでSeparatorが表示されなくなるため、`isHidden`によってSeparator表示を切り替えています。