LoginSignup
3
2

More than 3 years have passed since last update.

FloatingPanelを使うとStroybardで作ったtableViewがnilになる時

Last updated at Posted at 2020-12-25

結論、フロートさせるControllerをストーリーボードから生成しよう。

ちょっと練習でTikTokのコメント欄っぽいものを作ろうとしてFloatingPanelを使ったのですが、その際にtableViewがnilになってハマりました。

スクリーンショット 2020-12-25 21.58.58.png

ちゃんとIBOutletはキチンと紐付けられておりましたが、どうやらViewControllerでcontentViewを生成したときにClassから生成してるもんだから、Storyboardに配置したtableviewが読み込まれてなくてnilになってたようだ。

そこで生成時にfromStoryboard()関数を使ってストーリーボードからViewControllerを生成してやるようにすることで無事解決できた。

ViewController.swift
import UIKit
import FloatingPanel

class ViewController: UIViewController, FloatingPanelControllerDelegate {
    var fpc: FloatingPanelController!

    override func viewDidLoad() {
        super.viewDidLoad()

        fpc = FloatingPanelController()
        fpc.delegate = self // Optional // レイアウトなどを変更しないときは不要

        //let contentVC = CommenttViewController()
        let contentVC = CommentViewController.fromStoryboard()
        fpc.set(contentViewController: contentVC)

        // Track a scroll view(or the siblings) in the content view controller.
        fpc.track(scrollView: contentVC.tableView)

        // Add and show the views managed by the `FloatingPanelController` object to self.view.
        fpc.addPanel(toParent: self)
    }
}
CommentViewController.swift
import UIKit

class CommentViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    @IBOutlet weak var tableView: UITableView!
    @IBOutlet weak var commentCountLabel: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.delegate = self // ここでtableViewがnilになって落ちてた
        tableView.dataSource = self
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    static func fromStoryboard(_ storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)) -> CommentViewController {
        let controller = storyboard.instantiateViewController(withIdentifier: "CommentViewController") as! CommentViewController
        return controller
    }

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

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "CommentCell", for: indexPath) as! CommentCell
        return cell
    }
}

ストーリーボードからViewControllerを生成するにはStoryboard IDを設定してやる必要がありますのでこの点だけ注意。

スクリーンショット 2020-12-25 22.00.12.png

おまけ

なお、いつも忘れるのでおさらいですがtableViewの中に直接ProtoTypeCellを入れて作った場合は、以下のようなregisterは必要ないみたいです。ただnibでの登録とClassでの登録の違いを忘れた‥ので優しい人コメントで教えてくれるとうれしい‥。

tableView.register(UINib(nibName: "CommentCell", bundle: nil), forCellReuseIdentifier: "CommentCell") // storyboardではなく別途xibファイルを作ってCellをデザインしたとき?
tableView.register(CommentCell.self, forCellReuseIdentifier: "CommentCell") //

またストーリーボードの Connections Inspector の Outlets で、dataSourceとdelegateを紐付けていれば以下も不要ですが、ぼくはここはコードでやってます。

tableView.dataSource = self
tableView.delegate = self

参考

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2