由 NSFetchedResultsController 处理的 UICollectionView 单元格不重新填充图像
UICollectionView Cells Handled by NSFetchedResultsController not Repopulating Images
在过去的几天里,我一直在尝试通过在集合视图存在的视图中按下 'newCollection' 按钮,用新的数据图像填充 UICollectionView。我可以在我的控制台中看到正在下载图像数据,并且我可以在离开视图后看到填充的 CV 单元格,然后 return。知道为什么集合视图单元格没有实时更新吗?
这是我正在处理的内容:
https://github.com/tdangles81/Virtual-Tourist/tree/detail-view
@IBAction func newCollectionBtn(sender: AnyObject) {
getNewCollection()
}
func getNewCollection(){
if let newFetch = self.fetchedResultsController.fetchedObjects{
for object in newFetch{
let newImg = object as! ImgModel
self.sharedContext.deleteObject(newImg)
}
}
FlickrRequestClient.sharedInstance().getNewGeoImgs(selectedPin)
}
var sharedContext: NSManagedObjectContext {
return CoreDataStack.sharedInstance().managedObjectContext
}
func saveContext(){
return CoreDataStack.sharedInstance().saveContext()
}
lazy var fetchedResultsController: NSFetchedResultsController = {
let fetchRequest = NSFetchRequest(entityName: "Image")
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "id", ascending: true)]
fetchRequest.predicate = NSPredicate(format: "pin == %@", self.selectedPin)
let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest,
managedObjectContext: self.sharedContext,
sectionNameKeyPath: nil, cacheName: nil)
return fetchedResultsController
}()
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
var pinView = mapView.dequeueReusableAnnotationViewWithIdentifier("pin") as? MKPinAnnotationView
if pinView == nil{
pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "pin")
}else{
pinView?.annotation = annotation
}
return pinView
}
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return fetchedResultsController.sections?.count ?? 0
}
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
let sectionInfo = self.fetchedResultsController.sections![section]
print(sectionInfo.numberOfObjects)
return sectionInfo.numberOfObjects
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("DetailCell", forIndexPath: indexPath) as! ImageCollectionCell
let image = fetchedResultsController.objectAtIndexPath(indexPath) as! ImgModel
configureUI(cell, image: image, atIndexPath: indexPath)
return cell
}
func configureUI(cell: ImageCollectionCell, image: ImgModel, atIndexPath indexPath: NSIndexPath) {
if image.image != nil{
image.loadUpdateHandler = nil
cell.flickrImageView.image = image.image!
print("Image.image \(image.image!)")
self.saveContext()
}else{
image.loadUpdateHandler = {[unowned self] () -> Void in
dispatch_async(dispatch_get_main_queue(), {
self.collectionView.reloadData()
})
}
cell.flickrImageView.image = image.image
}
}
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath){
if collectionView.cellForItemAtIndexPath(indexPath) != nil {
let image = fetchedResultsController.objectAtIndexPath(indexPath) as! ImgModel
print(image)
}
}
func controllerWillChangeContent(controller: NSFetchedResultsController) {
insertedIndex = [NSIndexPath]()
updatedIndex = [NSIndexPath]()
deletedIndex = [NSIndexPath]()
}
func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
switch type {
case .Insert:
insertedIndex.append(newIndexPath!)
case .Update:
updatedIndex.append(indexPath!)
case .Move:
print("Surprise!")
case .Delete:
deletedIndex.append(indexPath!)
}
}
func controllerDidChangeContent(controller: NSFetchedResultsController) {
collectionView.performBatchUpdates({() -> Void in
for indexPath in self.insertedIndex {
self.collectionView.insertItemsAtIndexPaths([indexPath])
}
for indexPath in self.updatedIndex {
self.collectionView.reloadItemsAtIndexPaths([indexPath])
}
for indexPath in self.deletedIndex {
self.collectionView.deleteItemsAtIndexPaths([indexPath])
}
},completion: nil)
}
func addSpinner(cellView: UICollectionViewCell, activityBool: Bool){
let activitySpinner = UIActivityIndicatorView.init(activityIndicatorStyle: UIActivityIndicatorViewStyle.WhiteLarge)
activitySpinner.center = cellView.center
activitySpinner.color = UIColor.whiteColor()
activitySpinner.startAnimating()
if activityBool == true{
activitySpinner.startAnimating()
cellView.addSubview(activitySpinner)
}else if activityBool == false{
activitySpinner.stopAnimating()
cellView.willRemoveSubview(activitySpinner)
}
}
func removeSpinner(){
}
}
我在 NSFetchedResultsController 行为中遇到了问题。如果在获取请求时设置了 NSPredicate,则不会调用委托方法。
尝试去掉谓词,看看你是否也有这个问题。
我正在尝试查看它是否是 Xcode 中的错误,或者是与故障相关的一些未处理的错误,或者 NSFetchedResultsController class 中是否使用了新的查询令牌系统,我们需要做点什么。
在过去的几天里,我一直在尝试通过在集合视图存在的视图中按下 'newCollection' 按钮,用新的数据图像填充 UICollectionView。我可以在我的控制台中看到正在下载图像数据,并且我可以在离开视图后看到填充的 CV 单元格,然后 return。知道为什么集合视图单元格没有实时更新吗?
这是我正在处理的内容:
https://github.com/tdangles81/Virtual-Tourist/tree/detail-view
@IBAction func newCollectionBtn(sender: AnyObject) {
getNewCollection()
}
func getNewCollection(){
if let newFetch = self.fetchedResultsController.fetchedObjects{
for object in newFetch{
let newImg = object as! ImgModel
self.sharedContext.deleteObject(newImg)
}
}
FlickrRequestClient.sharedInstance().getNewGeoImgs(selectedPin)
}
var sharedContext: NSManagedObjectContext {
return CoreDataStack.sharedInstance().managedObjectContext
}
func saveContext(){
return CoreDataStack.sharedInstance().saveContext()
}
lazy var fetchedResultsController: NSFetchedResultsController = {
let fetchRequest = NSFetchRequest(entityName: "Image")
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "id", ascending: true)]
fetchRequest.predicate = NSPredicate(format: "pin == %@", self.selectedPin)
let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest,
managedObjectContext: self.sharedContext,
sectionNameKeyPath: nil, cacheName: nil)
return fetchedResultsController
}()
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
var pinView = mapView.dequeueReusableAnnotationViewWithIdentifier("pin") as? MKPinAnnotationView
if pinView == nil{
pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "pin")
}else{
pinView?.annotation = annotation
}
return pinView
}
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return fetchedResultsController.sections?.count ?? 0
}
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
let sectionInfo = self.fetchedResultsController.sections![section]
print(sectionInfo.numberOfObjects)
return sectionInfo.numberOfObjects
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("DetailCell", forIndexPath: indexPath) as! ImageCollectionCell
let image = fetchedResultsController.objectAtIndexPath(indexPath) as! ImgModel
configureUI(cell, image: image, atIndexPath: indexPath)
return cell
}
func configureUI(cell: ImageCollectionCell, image: ImgModel, atIndexPath indexPath: NSIndexPath) {
if image.image != nil{
image.loadUpdateHandler = nil
cell.flickrImageView.image = image.image!
print("Image.image \(image.image!)")
self.saveContext()
}else{
image.loadUpdateHandler = {[unowned self] () -> Void in
dispatch_async(dispatch_get_main_queue(), {
self.collectionView.reloadData()
})
}
cell.flickrImageView.image = image.image
}
}
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath){
if collectionView.cellForItemAtIndexPath(indexPath) != nil {
let image = fetchedResultsController.objectAtIndexPath(indexPath) as! ImgModel
print(image)
}
}
func controllerWillChangeContent(controller: NSFetchedResultsController) {
insertedIndex = [NSIndexPath]()
updatedIndex = [NSIndexPath]()
deletedIndex = [NSIndexPath]()
}
func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
switch type {
case .Insert:
insertedIndex.append(newIndexPath!)
case .Update:
updatedIndex.append(indexPath!)
case .Move:
print("Surprise!")
case .Delete:
deletedIndex.append(indexPath!)
}
}
func controllerDidChangeContent(controller: NSFetchedResultsController) {
collectionView.performBatchUpdates({() -> Void in
for indexPath in self.insertedIndex {
self.collectionView.insertItemsAtIndexPaths([indexPath])
}
for indexPath in self.updatedIndex {
self.collectionView.reloadItemsAtIndexPaths([indexPath])
}
for indexPath in self.deletedIndex {
self.collectionView.deleteItemsAtIndexPaths([indexPath])
}
},completion: nil)
}
func addSpinner(cellView: UICollectionViewCell, activityBool: Bool){
let activitySpinner = UIActivityIndicatorView.init(activityIndicatorStyle: UIActivityIndicatorViewStyle.WhiteLarge)
activitySpinner.center = cellView.center
activitySpinner.color = UIColor.whiteColor()
activitySpinner.startAnimating()
if activityBool == true{
activitySpinner.startAnimating()
cellView.addSubview(activitySpinner)
}else if activityBool == false{
activitySpinner.stopAnimating()
cellView.willRemoveSubview(activitySpinner)
}
}
func removeSpinner(){
}
}
我在 NSFetchedResultsController 行为中遇到了问题。如果在获取请求时设置了 NSPredicate,则不会调用委托方法。
尝试去掉谓词,看看你是否也有这个问题。
我正在尝试查看它是否是 Xcode 中的错误,或者是与故障相关的一些未处理的错误,或者 NSFetchedResultsController class 中是否使用了新的查询令牌系统,我们需要做点什么。