2017-09-18 5 views
1

コアデータを使用してコレクションビューのセルからインターネットからダウンロードした画像を保存すると、 'NSInternalInconsistencyException' ' - [UICollectionViewController loadViewメソッド]は、 『バイツ-38-t0r - ビュー - 8BC-XF-VDC』ペン先をロードしますがUICollectionViewを取得できませんでした。' albumViewControllerの私のコードがあります:コアデータを使用していますが、 'nibでエラーが発生しましたが、UICollectionViewを取得しませんでした。'

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>) { 
} 
} 

私はco私は成功しました。違いはありますか?ところで

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」の枝の上にあります。エラーをスローバージョンはUICollectionViewControllerのサブクラスであるのに対し

class albumViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, MKMapViewDelegate { .... } 

答えて

0

これらの2つの実装の間の主な違いは、離れCoreDataの使用から、「ワーキング」バージョンはUIViewControllerのサブクラスであるということです:

class albumViewController: coreDataCollectionViewController, MKMapViewDelegate { .... } 
class coreDataCollectionViewController: UICollectionViewController { .... } 

UICollectionViewControllersは、その根本viewUICollectionView、またはそのサブクラスであることが必要です。あなたのストーリーボードでは、albumVCにはcollectionViewがありますが、ルートビューではありません。エラーは、実際にもあるあなたのmapViewControllerシーンによってスローされること

class albumViewController: coreDataCollectionViewController, MKMapViewDelegate { .... } 
class coreDataCollectionViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource { .... } 

も注意してください:

ソリューションはUIViewControllerをサブクラス化し、コレクションビューのデリゲートとデータソースのプロトコルを採用するcoreDataCollectionViewControllerのクラス定義を変更することですcoreDataCollectionViewControllerのサブクラスで、ストーリーボードにはcollectionViewはありません。上記の修正はこれでも有効です。

+0

'UICollectionViewController'を 'UIViewController、UICollectionViewDelegate、UICollectionViewDataSource'に変更しようとしましたが、coreDataCollectionViewControllerにいくつかのエラーがあります。そしてそれを解決する方法? – Martin

+0

これらのエラーの詳細がなくても解くのは難しいです。しかし、UIViewControllerはその名前でプロパティを持たない(またはその名前を持つプロパティを追加する)ので、 'collectionView'への参照を削除する必要があります。 – pbasdf

関連する問題