UITableViewCellサブクラスでの「設定」メソッドの呼び出しを簡略化したいと思います。ただし、すべてのセットアップ方法が同じではありませんが、パラメータは同じ種類から継承されます。ジェネリックやプロトコルで毎回パラメータをキャストする必要はありませんか?UITableViewCellへのサブクラスのメソッドを、プロトコルまたは基本クラスに基づく汎用パラメータ値を使用して呼び出します。
まずはこのようなcellForRow-方法:
class DataSource<V : UIViewController, T: TableViewCellData, VM: ViewModel> : NSObject, UITableViewDataSource, UITableViewDelegate {
var dataCollection: TableViewDataCollection<T>!
var viewModel: VM!
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellData = dataCollection.object(for: indexPath)
let cell = tableView.dequeueReusableCell(withIdentifier: cellData.identifier(), for: indexPath)
if let setupableCell = cell as? CellDataSetupable {
setupableCell.setup(with: cellData, viewModel: viewModel)
}
return cell
}
}
protocol CellDataSetupable : class {
func setup(with cellData: TableViewCellData, viewModel: ViewModel)
}
どこcellDataとのViewModelで私のセットアップの細胞を。私の(多くの)カスタムUITableViewCellのサブクラスで
:HomeViewTableViewCellData
はTableViewCellData
と HomeViewModel
のサブクラスである
extension BlurbTableViewCell : CellDataSetupable {
func setup(with cellData: TableViewCellData, viewModel: ViewModel) {
guard let cellData = cellData as? HomeViewTableViewCellData else { return }
guard let viewModel = viewModel as? HomeViewModel else { return }
// Use cellData and viewModel to setup cell appearance
}
}
がViewModel
のサブクラスである代わりに、私はガードを削除し、直接このような何かを書きたいです:
extension BlurbTableViewCell : CellDataSetupable< {
func setup(with cellData: HomeViewTableViewCellData, viewModel: HomeViewModel) {
// Use cellData and viewModel to setup cell appearance
}
}
olutions(それが動作しません):
これはcellForRow方法で鋳造にエラーが発生ししかし、私は、「プロトコルのプロトコル上のassociatedtype/typealiasを使用することはできません...一般的な制約としてのみを使用することができますそれは自己またはそれに関連するタイプ要件があるからです。 "任意のアイデア
(も編集下記2を参照)How to create generic protocols in Swift?または私は私と一緒に暮らす必要があります:インターフェイスビルダーは、その後クラッシュするように私はまた、一般的な基底クラスを使用することはできません"Unknown class in interface builder file" when using class which inherits from a generic class in a Storyboard
:私はこの方法を試してみました鋳物?
編集1:
// This works fine
extension TransactionTableViewCell : CellDataSetupable {
typealias CellData = HomeViewTableViewCellData
typealias VM = HomeViewModel
func setup(with cellData: CellData, viewModel: VM) {
//Setup cell appearance ...
}
}
この行はまた、正常に動作します::私は(私はいくつかの一般的な種類の名前を変更したことに注意してください)このコードを試してみました下のネイト・マンからの提案の後 (余分なwhere句に注意してください)
class DataSource<VC : UIViewController, TVCD: TableViewCellData, VM: ViewModel, CDS: CellDataSetupable> : NSObject, UITableViewDataSource, UITableViewDelegate where CDS.TVCD == TVCD, CDS.VM == VM {
// ...
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellData = dataCollection.object(for: indexPath)
let cell = tableView.dequeueReusableCell(withIdentifier: cellData.identifier(), for: indexPath)
if let setupableCell = cell as? CDS {
setupableCell.setup(with: cellData, viewModel: viewModel)
}
return cell
}
しかし
class HomeTableViewDataSource: DataSource<HomeViewController, HomeViewTableViewCellData, HomeViewModel> {
から変更 Using 'CellDataSetupable' as a concrete type confirming to protocol 'CellDataSetupable' is not supported
編集2:
このエラーを与える
class HomeTableViewDataSource: DataSource<HomeViewController, HomeViewTableViewCellData, HomeViewModel, CellDataSetupable> {
からのUITableViewCellクラスのジェネリック基底クラスの具体的なバージョンを使用すると、いずれかのことはできません。 Why can't interface builder use a concrete generic subclass of of UIView?
お願いします。面白い。 – hasan83
私はcellwilldisplay tableviewデリゲートメソッドでセルパラメタの型を変更するだけで同じことをしようとしています。それは動作しません。このメソッドはオーバーライドとはみなされません。多分彼らはこのようにそれを実装しませんでした。 – hasan83
私を助けてくれてありがとう。これは正しい方向への試みかもしれません。しかし、それはDataSourceの私のサブクラスで不平を言う。 CellDataSetupableを汎用パラメータとして追加したので、これにいくつか入力する必要がありますが、 'CellDataSetupableプロトコルに準拠した具体的な型としてCellDataSetupableを使用することはサポートされていません。 'が生成されます。より多くのコードについては上記の「編集1」を参照してください。 – Sunkas