当我使用核心数据将从互联网上下载的一些图像保存在collectionView单元中时,我得到了一个错误‘NSInternalInconsistencyException’,原因是:‘-UICollectionViewController loadView加载了“BYZ-38-t0r-view-8bc-Xf-vdC”nib但没有获得UICollectionView。“下面是我的albumViewController代码:
class albumViewController: coreDataCollectionViewController, MKMapViewDelegate {
// Properties
@IBOutlet weak var mapView: MKMapView!
@IBOutlet weak var albumCollection: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
self.albumCollection.dataSource = self
self.albumCollection.delegate = self
// Show the pin
let spanLevel: CLLocationDistance = 2000
self.mapView.setRegion(MKCoordinateRegionMakeWithDistance(pinLocation.pinCoordinate, spanLevel, spanLevel), animated: true)
self.mapView.addAnnotation(pinLocation.pinAnnotation)
// Set the title
title = "Photo Album"
//Get the stack
let delegate = UIApplication.shared.delegate as! AppDelegate
let stack = delegate.stack
// Create a fetchrequest
let fr = NSFetchRequest<NSFetchRequestResult>(entityName: "Album")
fr.sortDescriptors = [NSSortDescriptor(key: "imageData", ascending: false),NSSortDescriptor(key: "creationDate", ascending: false)]
// Create the FetchedResultsController
fetchedResultsController = NSFetchedResultsController(fetchRequest: fr, managedObjectContext: stack.context, sectionNameKeyPath: nil, cacheName: nil)
// Put photos in core data
let photoURLs = Constants.photosUrl
for photoUrLString in photoURLs {
let photoURL = URL(string: photoUrLString)
if let photoData = try? Data(contentsOf: photoURL!) {
let photo = Album(imageData: photoData, context: fetchedResultsController!.managedObjectContext)
} else {
print("Image does not exist at \(photoURL)")
}
}
}
// Find number of items
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 9
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "photoCollectionViewCell", for: indexPath) as! photoCollectionViewCell
let album = fetchedResultsController!.object(at: indexPath) as! Album
performUIUpdatesOnMain {
cell.photoImageView?.image = UIImage(data: album.imageData as! Data)
}
return cell
}
// Reload photos album
@IBAction func loadNewPhotos(_ sender: AnyObject) {
}
}这是我的代码
class coreDataCollectionViewController: UICollectionViewController {
// Mark: Properties
var fetchedResultsController: NSFetchedResultsController<NSFetchRequestResult>? {
didSet {
// Whenever the frc changes, we execute the search and
// reload the table
fetchedResultsController?.delegate = self
executeSearch()
collectionView?.reloadData()
}
}
// Mark: Initializers
init(fetchedResultsController fc: NSFetchedResultsController<NSFetchRequestResult>, collectionViewLayout: UICollectionViewFlowLayout) {
fetchedResultsController = fc
super.init(collectionViewLayout: collectionViewLayout)
}
// Do not worry about this initializer. I has to be implemented because of the way Swift interfaces with an Objective C protocol called NSArchiving. It's not relevant.
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}
// Mark: CoreDataTableViewController (Subclass Must Implement)
extension coreDataCollectionViewController {
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
fatalError("This method MUST be implemented by a subclass of CoreDataTableViewController")
}
}
// Mark: CoreDataTableViewController (Table Data Source)
extension coreDataCollectionViewController {
override func numberOfSections(in collectionView: UICollectionView) -> Int {
if let fc = fetchedResultsController {
return (fc.sections?.count)!
} else {
return 0
}
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if let fc = fetchedResultsController {
return fc.sections![section].numberOfObjects
} else {
return 0
}
}
}
// Mark: CoreDataTableViewController (Fetches)
extension coreDataCollectionViewController {
func executeSearch() {
if let fc = fetchedResultsController {
do {
try fc.performFetch()
} catch let error as NSError {
print("Error while trying to perform a search: \n\(error)\n\(fetchedResultsController)")
}
}
}
}
// MARK: - CoreDataTableViewController: NSFetchedResultsControllerDelegate
extension coreDataCollectionViewController: NSFetchedResultsControllerDelegate {
func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
}
}但如果我不使用核心数据,我就会成功。有什么不同吗?
class albumViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, MKMapViewDelegate {
// Properties
@IBOutlet weak var mapView: MKMapView!
@IBOutlet weak var albumCollection: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
let spanLevel: CLLocationDistance = 2000
self.mapView.setRegion(MKCoordinateRegionMakeWithDistance(location.pinCoordinate, spanLevel, spanLevel), animated: true)
self.mapView.addAnnotation(location.pinAnnotation)
}
// Find number of items
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return Constants.photosUrl.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "photoCollectionViewCell", for: indexPath) as! photoCollectionViewCell
let photoURL = URL(string: Constants.photosUrl[(indexPath as NSIndexPath).item])
if let photoData = try? Data(contentsOf: photoURL!) {
performUIUpdatesOnMain {
cell.photoImageView?.image = UIImage(data: photoData)
}
} else {
print("Image does not exist at \(photoURL)")
}
return cell
}
// Reload photos album
@IBAction func loadNewPhotos(_ sender: AnyObject) {
}
} 顺便说一下,这是我的代码链接https://github.com/MartinSnow/MyVirtualTourist.git,我的项目在"storeLocation“分支上。
发布于 2017-09-19 15:57:10
除了使用CoreData之外,这两种实现之间的关键区别在于,“工作”版本是UIViewController的子类
class albumViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, MKMapViewDelegate { .... }而抛出错误的版本是UICollectionViewController的子类
class albumViewController: coreDataCollectionViewController, MKMapViewDelegate { .... }
class coreDataCollectionViewController: UICollectionViewController { .... }UICollectionViewControllers要求它们的根view是UICollectionView或它的子类。在情节提要中,albumVC有一个collectionView,但不是根视图。
解决方案是将coreDataCollectionViewController的类定义更改为UIViewController的子类,并采用集合视图委托和数据源协议:
class albumViewController: coreDataCollectionViewController, MKMapViewDelegate { .... }
class coreDataCollectionViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource { .... }另请注意,该错误实际上是由mapViewController场景引发的,该场景也是coreDataCollectionViewController的子类,并且在故事板中没有collectionView。上面的修复方法也应该适用于此。
https://stackoverflow.com/questions/46289489
复制相似问题