iOS その3 Advent Calendar
3日目も書かせていただきます!
予約投稿最高!
ちなみに前日も書かせていただきました!
では本題です。
UITableViewのSectionHeaderとSectionFooterをdequeuで使いまわしできるようにする
多分難しいことを考えなければ以下のUITableViewDelegate
を使って表示していると思います。
僕もそうでした。
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
処理をします。
以下のようなクラスを作成したとします。
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
を作成してください。
接続していきます。
これを使用していきます。
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に下線を表示する、しないを実装しました。