【Swift】TableViewControllerでTableViewのセクションが最前面に来てしまうので対応した

2022.01.11

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

TableViewControllerviewaddSubViewした時に意図していなかったUIになっていた為、対応しました。

環境

  • Xcode 13

コード

viewDidLoadImageViewUITableViewControllerviewaddSubViewしています。 この内容でビルドするとどんな結果になるでしょうか?

import UIKit

class TableViewController: UITableViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let imageView = UIImageView()
        imageView.image = UIImage(named: "adult")
        imageView.frame.size = CGSize(width: 200, height: 200)
        imageView.center = view.center
        view.addSubview(imageView)
    }

    // MARK: - Table view data source
    override func numberOfSections(in tableView: UITableView) -> Int {
        return 6
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 6
    }

    override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return String(section)
    }

    override func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
        guard let headerView = view as? UITableViewHeaderFooterView
        else { fatalError() }

        headerView.tintColor = .black
        headerView.textLabel?.textColor = .white
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")
        else { fatalError() }
        return cell
    }
}

結果

addSubViewしたImageViewよりTableViewのセクションが前面に来てしまい、目を覆ったような状態になってしまいました。

Debug View Hierarchy

どのような状態になっているかビュー階層を見てみることにしました。 案の定、追加したImageViewよりTableViewheaderViewが前面になっていることにより、意図しない目を隠されているような状態になってしまいました。

対応

viewDidAppearbringSubViewToFrontメソッドを使い、ImageViewを最前面に表示します。

class TableViewController: UITableViewController {

    private var imageView = UIImageView()

    override func viewDidLoad() {
        super.viewDidLoad()

        imageView = UIImageView()
        imageView.image = UIImage(named: "adult")
        imageView.frame.size = CGSize(width: 200, height: 200)
        imageView.center = view.center
        view.addSubview(imageView)
    }

    override func viewDidAppear(_ animated: Bool) {
        view.bringSubviewToFront(imageView)
    }

// 以下省略

bringSubviewToFront

UIViewのインスタンスメソッドで、パラメーターに渡したsubViewsubViewsの配列の最後尾に移動させることが出来ます。

func bringSubviewToFront(_ view: UIView)

そうすることによって、パラメーターで指定されたsubViewが親Viewの最前列に表示されます。

結果

補足

実はこの現象はUITableViewControllerを使用した時のみに発生している現象で、通常のUIViewControllerUITableViewを配置し、addSubViewした場合では、セクションが前面に表示されることはなく意図した通りの表示になっていました。

おわりに

罪のない人が何かやってしまった風になってしまいそうでしたが、セクションのViewを背面にすることができ、問題を無事に解決出来てよかったです。

参考