ios - 未调用 cellForItemAtIndexPath,原因不明

标签 ios swift core-data uicollectionview

我读过其他一些关于此问题的问题,这些问题与 CollectionView 的大小有关。我已经尝试按照这些答案中的建议调整大小,但它们都不起作用。我正在使用 NSFetchedResultsController ,它也为我进行了卷积(我想知道它是否与不触发有关)。

无论如何,真正的问题是我的 UICollectionView 没有显示任何内容。运行时没有错误,只是黑屏。我正在 Swift 中工作(显然)。

这是我在 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)
    })
}
}

我有打印语句确认 cellForItemAtIndexPath 未运行。有任何想法吗?我意识到这是非常具体的,我给出了大量代码,只是不太确定错误可能来自哪里。感谢您提前提供的任何帮助。

最佳答案

确保...您确认 UICollectionViewDelegate 协议(protocol)方法。
设置 collectionview.delegate = self
collectionview.datasource = self

关于ios - 未调用 cellForItemAtIndexPath,原因不明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35775621/

相关文章:

ios - 如何消除 UITableView 左侧的边距,而不在右侧创建间隙?

ios - 取消选择 Segment 的默认值

ios - 制定警报重复天数列表

ios - Core Data 中的电话号码存储

ios - 核心数据并发 `performBlockAndWait:` NSManagedObjectContext zombie

iphone - 在一对多关系 Coredata 中检索特定对象的信息

swift - 从 Tableview 中删除部分

objective-c - 如何在带有 OSX 的 SWIFT 中使用 Cocoa slider 控件

swift - 如何为 UIViewController 自定义子类创建非可选存储属性

ios - 无法从 SuperView 中删除自定义 UIView