2016-03-03 1 views
0

J'ai lu quelques autres questions à ce sujet que le problème lié à la taille de la CollectionView. J'ai essayé d'ajuster la taille comme recommandé dans ces réponses, mais aucun d'eux ne fonctionnait. J'utilise un NSFetchedResultsController qui convolute pour moi aussi (je me demande si cela a quelque chose à voir avec le fait qu'il ne se déclenche pas).cellForItemAtIndexPath pas appelé, pas clair pour savoir pourquoi

De toute façon, le vrai problème est que je n'ai aucun contenu apparaissant pour mon UICollectionView. Il n'y a pas d'erreurs à l'exécution, simplement un écran vide. Je travaille chez Swift (évidemment).

Voici mon code du ViewController:

import UIKit 
import CoreData 

private let reuseIdentifier = "Family" 
private var selectedFirstName:String = "Blank" 
private var selectedLastName:String = "Blank" 
private var selectedNumber:String = "Blank" 
private var selectedEmail:String = "Blank" 

class FamilyViewController: UIViewController, UICollectionViewDataSource { 

var coreDataStack: CoreDataStack! 
var fetchedResultsController: NSFetchedResultsController! 

@IBOutlet var familyCollectionView: UICollectionView! 

override func viewDidLoad() { 
    super.viewDidLoad() 

    //1 
    let fetchRequest = NSFetchRequest(entityName: "Family") 

    let firstNameSort = 
    NSSortDescriptor(key: "firstName", ascending: true) 

    fetchRequest.sortDescriptors = [firstNameSort] 

    //2 
    self.coreDataStack = CoreDataStack() 
    fetchedResultsController = 
     NSFetchedResultsController(fetchRequest: fetchRequest, 
      managedObjectContext: coreDataStack.context, 
      sectionNameKeyPath: nil, 
      cacheName: nil) 

    fetchedResultsController.delegate = CollectionViewFetchedResultsControllerDelegate(collectionView: familyCollectionView) 

    //3 
    do { 
     try fetchedResultsController.performFetch() 
    } catch let error as NSError { 
     print("Error: \(error.localizedDescription)") 
    } 
} 


func configureCell(cell: FamilyCCell, indexPath: NSIndexPath) { let family = fetchedResultsController.objectAtIndexPath(indexPath) as! Family 

    cell.firstNameLabel.text = family.firstName 
    print("configureCell ran") 

} 


override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
    // Dispose of any resources that can be recreated. 
} 

func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int { 
    // #warning Incomplete implementation, return the number of sections 
    print("numberOfSectionsInCollectionView ran") 
    return fetchedResultsController.sections!.count 
} 


func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 
    // #warning Incomplete implementation, return the number of items 
    let sectionInfo = fetchedResultsController.sections![section] 
    print("numberOfItemsInSection ran") 
    return sectionInfo.numberOfObjects 
} 


func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { 
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! FamilyCCell 

    print("cellForItemAtIndexPath ran") 
    configureCell(cell, indexPath: indexPath) 

    return cell 
} 




override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { 
    if (segue.identifier == "showDetail") { 
     let detailVC = segue.destinationViewController as! ContactViewController 

     print("prepareForSegue ran") 
     detailVC.detailFirstName = selectedFirstName 
     detailVC.detailLastName = selectedLastName 
     detailVC.detailNumber = selectedNumber 
     detailVC.detailEmail = selectedEmail 
    } 
} 
} 

extension FamilyViewController: UICollectionViewDelegate { 

func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) { 
    print("didSelectItemAtIndexPath ran") 
    collectionView.delegate = self 

    let family = fetchedResultsController.objectAtIndexPath(indexPath) as! Family 

    selectedFirstName = family.firstName! 
    selectedLastName = family.lastName! 
    selectedNumber = family.phone! 
    selectedEmail = family.email! 
    coreDataStack.saveContext() 
} 
} 


class CollectionViewFetchedResultsControllerDelegate: NSObject, NSFetchedResultsControllerDelegate { 

// MARK: Properties 

private let collectionView: UICollectionView 
private var blockOperations: [NSBlockOperation] = [] 

// MARK: Init 

init(collectionView: UICollectionView) { 
    self.collectionView = collectionView 
} 

// MARK: Deinit 

deinit { 
    blockOperations.forEach { $0.cancel() } 
    blockOperations.removeAll(keepCapacity: false) 
} 

// MARK: NSFetchedResultsControllerDelegate 

func controllerWillChangeContent(controller: NSFetchedResultsController) { 
    blockOperations.removeAll(keepCapacity: false) 
} 

func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) { 

    switch type { 

    case .Insert: 
     guard let newIndexPath = newIndexPath else { return } 
     let op = NSBlockOperation { [weak self] in self?.collectionView.insertItemsAtIndexPaths([newIndexPath]) } 
     blockOperations.append(op) 

    case .Update: 
     guard let newIndexPath = newIndexPath else { return } 
     let op = NSBlockOperation { [weak self] in self?.collectionView.reloadItemsAtIndexPaths([newIndexPath]) } 
     blockOperations.append(op) 

    case .Move: 
     guard let indexPath = indexPath else { return } 
     guard let newIndexPath = newIndexPath else { return } 
     let op = NSBlockOperation { [weak self] in self?.collectionView.moveItemAtIndexPath(indexPath, toIndexPath: newIndexPath) } 
     blockOperations.append(op) 

    case .Delete: 
     guard let indexPath = indexPath else { return } 
     let op = NSBlockOperation { [weak self] in self?.collectionView.deleteItemsAtIndexPaths([indexPath]) } 
     blockOperations.append(op) 

    } 
} 

func controller(controller: NSFetchedResultsController, didChangeSection sectionInfo: NSFetchedResultsSectionInfo, atIndex sectionIndex: Int, forChangeType type: NSFetchedResultsChangeType) { 

    switch type { 

    case .Insert: 
     let op = NSBlockOperation { [weak self] in self?.collectionView.insertSections(NSIndexSet(index: sectionIndex)) } 
     blockOperations.append(op) 

    case .Update: 
     let op = NSBlockOperation { [weak self] in self?.collectionView.reloadSections(NSIndexSet(index: sectionIndex)) } 
     blockOperations.append(op) 

    case .Delete: 
     let op = NSBlockOperation { [weak self] in self?.collectionView.deleteSections(NSIndexSet(index: sectionIndex)) } 
     blockOperations.append(op) 

    default: break 

    } 
} 

func controllerDidChangeContent(controller: NSFetchedResultsController) { 
    collectionView.performBatchUpdates({ 
     self.blockOperations.forEach { $0.start() } 
     }, completion: { finished in 
      self.blockOperations.removeAll(keepCapacity: false) 
    }) 
} 
} 

J'ai des déclarations d'impression confirmant que le cellForItemAtIndexPath ne fonctionne pas. Des idées? Je me rends compte que c'est assez spécifique et j'ai donné une tonne de code, mais je ne sais pas trop d'où l'erreur pourrait provenir. Merci d'avance pour toute aide.

+0

I crois que j'ai fait ça. Je les ai contrôlés en cliquant dessus dans le storyboard et connecté la collection à la source de données/délégué. Quelque chose avec le code viewcontroller que je devrais brancher là-bas? Je ne le pensais pas mais je pouvais certainement me tromper. – skind

+2

renvoyez-vous un nombre de sections et d'éléments non nul? – Sulthan

+0

J'interroge le NSFetchedResultsController pour le nombre de sections, il devrait donc renvoyer un nombre différent de zéro. – skind

Répondre

1

Assurez-vous ... vous de confirmer les méthodes du protocole UICollectionViewDelegate.
mis collectionview.delegate = self
collectionview.datasource = self

+0

Bien que cela soit généralement le cas, il ne corrige pas ce code. Je les ai déjà branchés. – skind

+0

Juste pour clarifier à quiconque lisant ceci plus tard, j'ai changé mon code pour ne pas référencer un "CoreDataStack". Au lieu de cela, j'ai simplement créé une variable NSObject dans ce viewController et j'ai réussi à le faire fonctionner de cette façon. J'accepte cette réponse comme typiquement, ce serait le problème (délégué/source de données non connecté). – skind

0

dans la vue de la collecte source de données pour les méthodes numberOfSectionsInCollectionView retour 1 et à collectionViewNumberOfCellsForSection retour le nombre de cellules que vous souhaitez afficher

à Clarify tableview ou une collection voir une « section » est un groupe de choses connexes où, en tant que cellule (ou rangée pour tableview) sont les choses réelles que vous voulez afficher - quand vous ne surchargez pas le nombre de cellules requis, il retournera 0 pour toutes les sections

(ill check the méthode exacte res du matin et de modifier si elles sont légèrement)

0

Écrivez-le:

class FamilyViewController: UIViewController, UICollectionViewDataSource,UICollectionViewDelegate{ 

et à écrire ces deux lignes dans votre méthode viewDidLoad:

familyCollectionView.delegate = self 

familyCollectionView.datasource = self