Help us understand the problem. What is going on with this article?

【iOS】UITableViewのSectionHeaderとSectionFooterをdequeuで使いまわしできるようにする

More than 3 years have passed since last update.

iOS その3 Advent Calendar

3日目も書かせていただきます!

予約投稿最高!

ちなみに前日も書かせていただきました!

では本題です。

UITableViewのSectionHeaderとSectionFooterをdequeuで使いまわしできるようにする

多分難しいことを考えなければ以下のUITableViewDelegateを使って表示していると思います。

僕もそうでした。

ViewController.swift
class ViewController {
    @IBOutlet weak var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()
        self.tableView.delegate = self
    }
}

extension ViewController: UITableViewDelegate {

    func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        // 適当な高さ
        return 80.0
    }

    func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        return CustomView()
    }

}

という感じかと思います。

ただそうすると以下の問題があります。

  • 他のイベント時にSection Header, Section Footerにアクセスすることができません。
  • なんか毎回生成処理するのめんどくさい

ちなみにですが...

UITableViewには以下のメソッドがあります。

  • func headerView(forSection section: Int) -> UITableViewHeaderFooterView?
  • func footerView(forSection section: Int) -> UITableViewHeaderFooterView?

というメソッドがありますが、上記の作り方だとアクセスしてもnilが返ってくるだけです。

このメソッドからアクセスできるようにしたいと思います。

UITableViewHeaderFooterView

最初はクラスで

UITableViewHeaderFooterViewを継承したクラスを作成してregister処理をします。

以下のようなクラスを作成したとします。

CustomTableViewHeaderFooterView.swift
class CustomTableViewHeaderFooterView: UITableViewHeaderFooterView {
    // 適当にレイアウト処理を施しているであろうLabel
    private let label: UILabel

    func setText(_ text: String?) {
        self.label.text = text
    }

}

これを大好きregister処理をします。

class ViewController {

    @IBOutlet weak var tableView: UITableView!

    // identifier
    private let headerfooterViewIdentifier = "CustomTableViewHeaderFooterView"

    override func viewDidLoad() {
        super.viewDidLoad()
        self.tableView.delegate = self

        self.tableView.register(CustomTableViewHeaderFooterView.self, forHeaderFooterViewReuseIdentifier: headerfooterViewIdentifier)
    }

}

で使うときは

extension ViewController: UITableViewDelegate {

    func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        // 適当な高さ
        return 80.0
    }

    func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let view = tableView.dequeueReusableHeaderFooterView(withIdentifier: headerfooterViewIdentifier)
        if let v = view as? CustomTableViewHeaderFooterView {
            v.setText("header!!!")
        }
        return view
    }

}

となります。

それではNibファイルを使って

やってみます。

以下のようなCustomTableViewHeaderFooterView.xibを作成してください。

スクリーンショット 2016-11-28 0.25.22.png

接続していきます。

スクリーンショット 2016-11-28 0.30.50.png

これを使用していきます。

class ViewController {

    @IBOutlet weak var tableView: UITableView!

    // identifier
    private let nibName = "CustomTableViewHeaderFooterView"

    override func viewDidLoad() {
        super.viewDidLoad()
        self.tableView.delegate = self

        let nib = UINib(nibName: nibName, bundle: nil)
        self.tableView.register(nib, forHeaderFooterViewReuseIdentifier: nibName)
    }

}

で使うときは

extension ViewController: UITableViewDelegate {

    func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        // 適当な高さ
        return 80.0
    }

    func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let view = tableView.dequeueReusableHeaderFooterView(withIdentifier: nibName)
        if let v = view as? CustomTableViewHeaderFooterView {
            v.setText("header!!!")
        }
        return view
    }

}

となります。

ちなみに他のイベントなどでsectionの色を変えたいなどの場合は

// 取得したいseciton
let section = 0
let view = self.tableView.headerView(forSection: section)
view.backgroundColor = UIColor.blue

というように扱うことができます。

終わりに

僕はこれでUITableViewのスクロールに合わせてSectionに下線を表示する、しないを実装しました。

参考

ryokosuge
金髪iOS エンジニア なんか色々やってます
https://ryokosuge.github.io/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away