2017-11-22 1 views
1

In meinem Sichtcontroller möchte ich zwei Sammlungsansichten haben. Nachdem ich das versucht habe, bekam ich einen Sigabrt-Fehler und meine App stürzt ab. Ich prognostiziere, dass das Problem liegt, weil ich die Datenquelle dieser Sammlungsansichten selbst zuweisen. Ich falsch sein kann, hier ist mein Code:Zwei Sammlungsansichten mit verschiedenen Wiederverwendungszellen in einer Ansicht Controller

Im Hinblick tat Last, i die Datenquelle der Sammlung Ansichten gesetzt:

@IBOutlet var hashtagCollectionView: UICollectionView! 
@IBOutlet var createCollectionView: UICollectionView! 

override func viewDidLoad() { 
    super.viewDidLoad() 
    createCollectionView.dataSource = self 
    hashtagCollectionView.dataSource = self 
} 

Dann habe ich eine Erweiterung für den UICollectionViewDataSource erstellen

extension CategoryViewController: UICollectionViewDataSource { 

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 
    var returnValue = 0 

    if collectionView == hashtagCollectionView { 
     // Return number of hashtags 
     returnValue = hashtags.count 
    } 

    if collectionView == createCollectionView { 
     // I only want 3 cells in the create collection view 
     returnValue = 3 
    } 
    return returnValue 
} 

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 
    var return_cell: UICollectionViewCell 

    // Place content into hashtag cells 
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "hashtagCell", for: indexPath) as! TrendingTagsCollectionViewCell 
    cell.hashtagText = hashtags[indexPath.row] 

    // Place content in creators cell 
    let createCell = collectionView.dequeueReusableCell(withReuseIdentifier: "createCell", for: indexPath) as! CreateCollectionViewCell 
    createCell.text = creators[indexPath.row] 
    createCell.image = creatorImages[indexPath.row] 

    // Is this the right logic? 
    if collectionView == hashtagCollectionView { 
     return_cell = cell 
    } else { 
     return_cell = createCell 
    } 
    return return_cell 
} 

} 

Antwort

3

Dies stürzt ab, weil Ihre if-Anweisung in collectionView(_:cellForItemAt:) nicht genügend Masse abdeckt.

Während Sie Recht haben, dass Sie eine andere Zelle zurückgeben müssen, basierend auf dem, was Sammlungsansicht fragt, können Sie dequeueReusableCell(withReuseIdentifier:for:) nicht zweimal mit anderen Bezeichnern wie diesem aufrufen. Da Sie beide Male die gleiche Sammlungsansicht anfordern, ist es sehr wahrscheinlich, dass einer der Identifikatoren nicht in dieser Sammlungsansicht registriert ist.

Stattdessen sollten Sie die if erweitern nur um die Gesamtheit dieses Verfahren zu decken:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 
    if collectionView == hashtagCollectionView { 
     // Place content into hashtag cells 
     let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "hashtagCell", for: indexPath) as! TrendingTagsCollectionViewCell 
     cell.hashtagText = hashtags[indexPath.row] 
     return cell 
    } else if collectionView == createCollectionView { 
     // Place content in creators cell 
     let createCell = collectionView.dequeueReusableCell(withReuseIdentifier: "createCell", for: indexPath) as! CreateCollectionViewCell 
     createCell.text = creators[indexPath.row] 
     createCell.image = creatorImages[indexPath.row] 

     return cell 
    } else { 
     preconditionFailure("Unknown collection view!") 
    } 
} 

, dass nur eine Zelle einmal aus der Warteschlange entfernt versucht, je nachdem, welche Sammlung Ansicht fragt, und setzen die zurück Zelle zur richtigen Klasse.

N.B. Diese Art von Ansatz funktioniert für eine Weile, aber auf lange Sicht können Sie sehr lange UICollectionViewDataSource-Methodenimplementierungen erhalten, die alle in einer Reihe von if-Anweisungen verpackt sind. Es könnte sich lohnen, Ihre Datenquellen in separate kleinere Klassen aufzuteilen.

+0

Danke testen sollen, funktioniert dies! – vApp

1
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 
     if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "hashtagCell", for: indexPath) as? TrendingTagsCollectionViewCell { 
      cell.hashtagText = hashtags[indexPath.row] 
      return cell 
     } 

     if let createCell = collectionView.dequeueReusableCell(withReuseIdentifier: "createCell", for: indexPath) as? CreateCollectionViewCell { 
      createCell.text = creators[indexPath.row] 
      createCell.image = creatorImages[indexPath.row] 
      return createCell 
     } 
     return UICollectionViewCell() // or throw error here 
    } 
0

ich Ihren Code Absturz mit einer Null denken, wenn Wiederverwendung Zelle

Sie cellForItemAt wie diese

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 
    if collectionView == hashtagCollectionView { 
     // Place content into hashtag cells 
     let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "hashtagCell", for: indexPath) as! TrendingTagsCollectionViewCell 
     cell.hashtagText = hashtags[indexPath.row] 
     return cell 
    } else { 
     // Place content in creators cell 
     let createCell = collectionView.dequeueReusableCell(withReuseIdentifier: "createCell", for: indexPath) as! CreateCollectionViewCell 
     createCell.text = creators[indexPath.row] 
     createCell.image = creatorImages[indexPath.row] 
     return createCell 
    } 
} 
Verwandte Themen