でもuglyのコードを修正しようとしています。スイフト:変数テーブルとしてキャストテーブルセル
私のアプリには5つのTableViewがあり、それぞれ異なるタイプのデータを表示します(セルのレイアウトが異なる)。データ型は似ていて類似したメソッド(ダウンロード、エンコーディングなど)が必要なため、私はTableViewController:UITableViewControllerクラスを設定して、5つのTableViewControllerサブクラスのスーパークラスとして機能します。このスーパークラスの中で、私は標準の "cellForRowAt"メソッドを持っていますが、膨大かつ繰り返しています。私はそれを簡素化したい。
私の問題(私は思う)は複数の "let cell ="ステートメントで、データ型に応じて異なるタイプのTableViewCellとしてキャストされます。たとえば、私のDataType.SCHEDULESデータ型は、 "SchedulesCell"というreuseIDを持つSchedulesTableViewCellを取得する必要があります。彼らはそれぞれ独自のIBOutletビューを持っているので、私はそれらをすべて同じTableViewCellクラスにすることはできません。
醜いことに、各tableViewには2つのセルプロトタイプがあり、各データ型に対してARTICLEセルとDETAILセルを生成できる必要があります。
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// get the article and row type
let article = getArticleFor(indexPath: indexPath)
let cellType = getCellTypeFor(indexPath: indexPath)
// create either an ARTICLE row or a DETAIL row.
// (simplified for SO posting. Each "case" is actually
// 5-6 lines of nearly identical code)
switch cellType {
// for the ARTICLE cell prototype
case CellType.ARTICLE:
// get the right table cell matching the datatype
switch self.datatype {
case DataType.SCHEDULES:
let cell = tableView.dequeueReusableCell(withIdentifier: "SchedulesCell") as! SchedulesTableViewCell
cell.fillCellWith(article: article)
cell.otherMethod2()
cell.otherMethod3()
return cell
case DataType.LUNCH:
let cell = tableView.dequeueReusableCell(withIdentifier: "LunchCell") as! LunchTableViewCell
cell.fillCellWith(article: article)
cell.otherMethod2()
cell.otherMethod3()
return cell
case DataType.EVENTS:
let cell = tableView.dequeueReusableCell(withIdentifier: "EventsCell") as! EventsTableViewCell
cell.fillCellWith(article: article)
cell.otherMethod2()
cell.otherMethod3()
return cell
case DataType.DAILY_ANN:
let cell = tableView.dequeueReusableCell(withIdentifier: "DailyannCell") as! DailyannTableViewCell
cell.fillCellWith(article: article)
cell.otherMethod2()
cell.otherMethod3()
return cell
case DataType.NEWS:
let cell = tableView.dequeueReusableCell(withIdentifier: "NewsCell") as! NewsTableViewCell
cell.fillCellWith(article: article)
cell.otherMethod2()
cell.otherMethod3()
return cell
}
// or for the DETAIL cell prototype
case CellType.DETAIL:
// get the right table cell matching the datatype
switch self.datatype {
case DataType.SCHEDULES:
let cell = tableView.dequeueReusableCell(withIdentifier: "SchedulesDetailsCell") as! ScheduleDetailTableViewCell
cell.fillCellWith(article: article)
cell.otherMethod2()
cell.otherMethod3()
return cell
case DataType.LUNCH:
let cell = tableView.dequeueReusableCell(withIdentifier: "LunchDetailsCell") as! LunchDetailsTableViewCell
cell.fillCellWith(article: article)
cell.otherMethod2()
cell.otherMethod3()
return cell
case DataType.EVENTS:
let cell = tableView.dequeueReusableCell(withIdentifier: "EventsDetailsCell") as! EventsDetailTableViewCell
cell.fillCellWith(article: article)
cell.otherMethod2()
cell.otherMethod3()
return cell
case DataType.DAILY_ANN:
let cell = tableView.dequeueReusableCell(withIdentifier: "DailyannDetailCell") as! DailyannDetailsTableViewCell
cell.fillCellWith(article: article)
cell.otherMethod2()
cell.otherMethod3()
return cell
case DataType.NEWS:
let cell = tableView.dequeueReusableCell(withIdentifier: "NewsDetailCell") as! NewsDetailTableViewCell
cell.fillCellWith(article: article)
cell.otherMethod2()
cell.otherMethod3()
return cell
}
}
}
私はもともとサブクラス自身の 『cellForRowAt』メソッド内の各「聞かせてセル=」ケースがあったが、私は愚かに思えたすべてのサブクラスに非常によく似たコードを繰り返しました。一方、上のコードは反復を単一のクラスに移動しましたが、反復を削除しなかったので、それはまだ愚かですが、別の場所です。
私は、このような何かをするクラスの辞書を作ることができれば、私はその後、私のような、より一般的な私の「聞かせてセル=」文を作ることができる...
let tableCellClasses = [DataType.SCHEDULES : ScheduleTableViewCell,
DataType.LUNCH : LunchTableViewCell
etc.
...のように感じます...
let cell = tableView.dequeueReusableCell(withIdentifier: identifier[dataType]) as! tableCellClasses[dataType]
しかし、それを動作させる方法を見つけることができないようです。
私が言ったように、それは動作しますが、それは醜いです。私は高校で働いているので、クリーンで構造の整ったコードを見るためにレポを見ている学生に欲しいです。
提案がありますか?
TableViewCell基本クラスを作成すると、サブクラスのIBOutletビューにアクセスできなくなります。したがって、私が "let cell ="ステートメントを呼び出すとき、それらが基本クラスとしてキャストされていれば、基本クラス・メソッドはサブクラス・セル・ビューに移入できません。 私は誤解していますか? –
私は、identifiy inpsectorの各プロトタイプセルに適切なサブクラスを設定すると、ストーリーボードは要求されたとおりにインスタンス化すると思います。基本クラスへのキャストは基本クラスのインスタンスに変換されませんが、それはコンパイルエラーを起こさずに 'fillCellWith(article:)'を呼び出すことができます。特定のサブクラスがメソッドをオーバーライドする場合は、オーバーライドされた実装が呼び出されます。コンセント設定はセルのサブクラスのソースコードで実行する必要があります。したがって、テーブルビューコントローラから分離された実装の詳細です。 –
おそらく、 'dequeueReusableCell(withIdentifier :, for:)'を使用してください。 –