2017-01-26 11 views
1

UICollectionViewにますます多くのセルタイプを追加する一方で、コードを維持するのが難しいことに気付きました。したがって、新しい機能を追加しながらコードを変更すべきではないという原則に従えば、新しいコードを追加する必要があります。UICollectionViewのスイッチを持たないデキュー再利用可能なセル

例から始めましょう。

私たちは、このようなデータモデルがあります:

protocol Animal {} 

class Dog: Animal {} 

class Duck: Animal {} 

をそして、我々は適切な2個のセルがある - DogCellDuckCellを。

多くのチュートリアルによると、私たちは今、私たちはCatモデルに基づいCatCellある別のセルを追加したいUICollectionViewDataSource

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 
    let animal = self.animals[indexPath.row] 
    if let dog = animal as? Dog { 
     return collectionView.dequeueReusableCell(withReuseIdentifier: "DogCell", for: indexPath) 
    } else if let duck = animal as? Duck { 
     return collectionView.dequeueReusableCell(withReuseIdentifier: "DuckCell", for: indexPath) 
    } 
    return UICollectionViewCell() 
} 

から機能的にこのような何かを実装することができます。

コードをきれいにするために別のelse ifを追加することは悪い習慣なので、iOSでどのように行うのですか?そのための良いデザインパターンはありますか? Objective-Cコードも高く評価されます。

+0

私は、else-ifステートメントを使用すると実際には(おそらく最も簡単な)方法だと言います。それについて考えるなら、問題はelse-if文を追加することではなく、もっと多くのクラスを追加することだと思います。クラスを追加するほど、より多くのカスタムセルを設計する必要があります。 else-ifステートメントは、このコードの使用の兆候です。 –

+0

私はそれがクリーンなコードの良い習慣だとは思わない。 collectionViewメソッドでこのようなif-else文が多数ある大きなプロジェクトの例はありますか? – Tajnero

答えて

1

セルの識別子に計算された文字列変数を持つ新しいプロトコルを追加します。

protocol AnimalCell { 
    var cellReuseIdentifier: String { get } 
} 

動物プロトコールはプロコルに従ってください。

extension Animal: AnimalCell { } 

、その後クラスに

extension Dog: Animal { 
    var cellReuseIdentifier: String { 
     return "DogCell" 
    } 
} 

extension Duck: Animal { 
    var cellReuseIdentifier: String { 
     return "DuckCell" 
    } 
} 

をcellReuseIdentifierを追加し、あなたは、単に識別子としてcellReuseIdentifierを設定します。

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 
    let animal = self.animals[indexPath.row] 
    return collectionView.dequeueReusableCell(withReuseIdentifier: animal.cellReuseIdentifier, for: indexPath) 
} 
+0

厳密にモデルクラスであるクラスは、UICollectionViewとは関係なく時々使用されるため、セルに関する情報を保持してはいけないと思いませんか? – Tajnero

+2

だからこそ、それをエクステンションに入れたのです。 2つの選択肢があります:if-elseやswitchでコード化されているか、クラス自体に知識を入れるかどうかといった、ある種のマップです。あなたが思いつくものは、これら2つのアプローチのバリエーションです。だからあなたがどれくらい純粋になりたいのか、醜いか保守不能なのかによって決まります。 – Avi

+0

私は@Aviに同意します。私はまた、情報がクラスに固有のものであれば、クラス自体にUI関連のものに関する情報を格納することには間違いがないと考えています。提案として、 'AnimalCell'プロトコルと拡張モジュールを別のファイル、おそらくセルのファイルに入れて、それがUIに関連していることを示すことができます。 – Yannick

関連する問題