ProMotion::TableScreenでViewCellにviewを追加する方法
ProMotion::TableScreenでは、デフォルトでTableViewで使うデータに追加したいviewをsubviewsというキーで含めておけば追加してくれます。
class MyScreen < ProMotion::TableScreen def table_data @table_data = [ cells: [ { title: 'cell 1', subviews: [label_1_1, label_1_2] }, { title: 'cell 2', subviews: [label_2_1, label_2_2] }, ] ] end end
label_1_1 label_1_2 等はViewCell中での表示位置や表示内容などを設定済み。
こうすることで、PM::TableScreenがcellを作成する際に、subviewsから追加するviewを拾ってaddSubviewしてくれます。
しかもdequeuereusablecellwithidentifierでcellが再利用される際、(度々大抵の人が陥るであろう)"再利用される前にaddSubviewされているview" あるいは "多重にaddSubviewしてしまう" 問題についても、PM::TableScreenがうまくremoveFromSuperviewしてから再度addSubviewしてくれるので安心です。
ProMotion gem すばらしい
しかし、cellへ追加したいviewのコードがScreen(ViewController)に書かなくてはいけないため、自分のコードが"糞コードの海"に沈みかねません。
そこでProMotionでは ProMotion::TableViewCell というUITableViewCellを継承してProMotionでViewCellをうまく扱うためのmoduleをincludeしたクラスが用意されてます。
例に、title(textLabel)もsubtitle(detailLabel)も使ってしまっているので、一つlabelを追加してcountを表示するViewCellを作ってみることにしましょう
今回はtable_dataのcellsにはsubviewsは使わずに、cell_classとcell_styleを追加し、それぞれ作成したMyTableViewCellとsubtitleを使うのでUITableViewCellStyleSubtitleを設定します。
あとは、MyTableVlewCellでsetupメソッドを上書きしてsuperを呼んでデフォルトの初期化処理をさせつつ、追加したいviewを準備した後に再度setup_subviewsを呼びます。
class MyScreen < ProMotion::TableScreen def table_data @table_data = [ cells: [ { title: 'cell 1', subtitle: 'sub title 1', count: 100, cell_class: MyTableViewCell, cell_style: UITableViewCellStyleSubtitle, }, { title: 'cell 1', subtitle: 'sub title 1', count: 0, cell_class: MyTableViewCell, cell_style: UITableViewCellStyleSubtitle, }, ] ] end end class MyTableVlewCell < ProMotion::TableViewCell attr_accessor :count def setup(data_cell, screen) super # super呼んで本来の初期化処理とかさせる1度目のset_subviewsも呼ばれる count_label = UILabel.new.tap do |label| # frameとかfontとか略 l.text = self.count end data_cell[:subviews] = [count_label] # data_cellはtable_dataのcellsの配列が1つ入ってる感じ set_subviews # 2度目のset_subviews self end end
この方法だと、"data_cell[:subviews] が(nilなので実質処理されないけど)、superにより1度に無駄に呼ばれる" などの無駄っぽい処理がありますが、ViewCellに関する処理が1カ所にまとめられるのは利点じゃないでしょうか。
以上、ProMotionのwikiにも書かれていないsubviewの追加方法でしたー