カスタムセルについてハマったので、備忘録として久々に記事を投稿しました。
まず、カスタムセルを作るときはクラスを作成する時に 「Also create XIB file」のチェックを忘れない…。
最初 StoryBoard の ViewController に配置した TableView の中で カスタムセルをレイアウトしていたが…あとで xibに切り分けたい…と思った時に、xibファイルだけを追加する方法がわからなかった…。なので、カスタムセルを作成するときは xibファイル付き で作成したほうがいい…。
なぜ StoryBoard から切り分けたいと思ったというと、…クラスを再利用することはできるが、ViewController ごとにレイアウトを毎回用意しないといけなかったから…。(逆に、特定のViewControllerではデザインを変えたいときはいいのかも…)
また、StoryBoard に作ってしまったカスタムセルを xibファイルの方へ移動させたかったが…配置させたレイアウトは全て破棄されて配置し直した…。(レイアウトが崩れずにコピペできる方法を知りたい…. orz
また、TableView の中の変化は KVO で監視しないほうがいいのかな…というのが自分の教訓です。
カスタムセルの中に置いた Slider を操作したとき、TableViewがある ViewController 側で変化を感知したかったので KVO で監視していたのですが…。
tableView(:cellForRowAt) で セルが作成されるときに カスタムセルだったら KVO を追加 … のような実装をしていたので、「KVOの破棄をどうしよう?」とは思っていたが、当初は問題なさげだったので、「まぁ…大丈夫なのかな?」と放置してました…。
当初は カスタムセルの数が2、3程度だったので問題なかったのですが、次第に増え…、6個ぐらいにまで増えると…TableViewも上下にスクロールさせることになり…ここで問題が発覚しました。
見えなくなったセルと再び見えるようになったセルで Slider の数値がおかしくなることに気がつきました。最初はインスタンス変数がどこでおかしくなってしまったのかわからなかったのですが、「セルのリサイクル」が起因かな?と薄々感づきました。 ^^;;
どうしたらいいかな…と悩みましたが、素直にKVOによる監視をやめ、カスタムセルには クロージャーを用意しました。
tableView(:cellForRowAt) の中で セルを tableView.dequeueReusableCell(withIdentifier:) で生成したときに毎回 クロージャー を渡すことで変化を感知でき、セルがリサイクルされても問題が起きなくなりました。
これからは、「TableViewで使うセルはリサイクルされる」ことを前提で実装することを心がけようと思います。^^;