cellForItemAtIndexPath没有被调用,不明白为什么

时间:2016-03-03 15:00:32

标签: ios swift core-data uicollectionview

我已经阅读了其他一些问题,这个问题与CollectionView的大小有关。我已经尝试按照这些答案中的建议调整大小,但没有一个能够正常工作。我正在使用一个NSFetchedResultsController,它也为我卷曲(我想知道它是否与它没有发射有关)。

无论如何,真正的问题是我没有为我的UICollectionView出现内容。运行时没有错误,只是一个空白屏幕。我在斯威夫特工作(显然)。

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

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

3 个答案:

答案 0 :(得分:1)

确保...确认UICollectionViewDelegate协议方法 设置collectionview.delegate = self
collectionview.datasource = self

答案 1 :(得分:0)

在方法using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; namespace Monitoring { public static class NativeCallsWrapper { private static SYSTEM_INFO sysInfo = new SYSTEM_INFO(); private static MEMORYSTATUSEX mem = new MEMORYSTATUSEX(); [DllImport("kernel32.dll", SetLastError = false)] public static extern void GetSystemInfo([In, Out] SYSTEM_INFO Info); [return: MarshalAs(UnmanagedType.Bool)] [DllImport("kernel32.dll", SetLastError = true)] static extern bool GlobalMemoryStatusEx([In, Out] MEMORYSTATUSEX lpBuffer); static NativeCallsWrapper() { GetSystemInfo(sysInfo); GlobalMemoryStatusEx(mem); } [StructLayout(LayoutKind.Explicit)] public struct SYSTEM_INFO_UNION { [FieldOffset(0)] public UInt32 OemId; [FieldOffset(0)] public UInt16 ProcessorArchitecture; [FieldOffset(2)] public UInt16 Reserved; } public struct SYSTEM_INFO { public SYSTEM_INFO_UNION CpuInfo; public UInt32 PageSize; public UInt32 MinimumApplicationAddress; public UInt32 MaximumApplicationAddress; public UInt32 ActiveProcessorMask; public UInt32 NumberOfProcessors; public UInt32 ProcessorType; public UInt32 AllocationGranularity; public UInt16 ProcessorLevel; public UInt16 ProcessorRevision; } [StructLayout(LayoutKind.Sequential)] public class MEMORYSTATUSEX { public uint dwLength; public uint dwMemoryLoad; public ulong ullTotalPhys; public ulong ullAvailPhys; public ulong ullTotalPageFile; public ulong ullAvailPageFile; public ulong ullTotalVirtual; public ulong ullAvailVirtual; public ulong ullAvailExtendedVirtual; public MEMORYSTATUSEX() { this.dwLength = (uint)Marshal.SizeOf(typeof(MEMORYSTATUSEX)); } } public static GeneralStatistics getGeneralStatistics() { GeneralStatistics generalStatistics = new GeneralStatistics(); generalStatistics.numberOfProcesses = (int)sysInfo.NumberOfProcessors; generalStatistics.memoryTotal = mem.ullTotalPhys / 1048; generalStatistics.memoryInUse = (mem.ullTotalPhys - mem.ullAvailPhys) / 1048; return generalStatistics; } } } 的集合视图数据源中返回1并在numberOfSectionsInCollectionView中返回要显示的单元格数

要澄清tableview或集合视图,“section”是一组相关的事物,其中作为单元格(或tableview的行)是您要显示的实际内容 - 当您不覆盖所需的单元格数量时它将为所有部分返回0

(在早上检查确切的方法签名并编辑它们是否稍微关闭)

答案 2 :(得分:0)

写下来:

class FamilyViewController: UIViewController, UICollectionViewDataSource,UICollectionViewDelegate{ 

并在viewDidLoad方法中写下这两行:

familyCollectionView.delegate = self

familyCollectionView.datasource = self