我正在開發一個iOS應用程序,並在某個時間點存儲用戶在Core Data中繪製的圖像。 現在我想將所有錄製的圖像加載到UICollectionView中,以便用戶可以選擇一個並在社交網絡上共享。 除了這最後一部分,我的應用程序中的所有東西都可以工作。 我跟着網上的各種教程,但我可以在UICollectionView上找到的所有例子都是使用來自Flickr或類似網站的圖片。從核心數據加載UICollectionView
這是我在這一點上代碼:
#import "LibraryViewController.h" (The name of the class we're in)
#import "SocialViewController.h"
#import "CollectionViewCell.h"
static NSString *cellIdentifier = @"MemeCell";
@implementation LibraryViewController {
NSMutableArray *_objectChanges;
NSMutableArray *_sectionChanges;
}
#pragma mark - View Controller LifeCycle
- (void)awakeFromNib
{
[super awakeFromNib];
}
- (void)viewDidLoad
{
[super viewDidLoad];
_objectChanges = [NSMutableArray array];
_sectionChanges = [NSMutableArray array];
self.title = @"Meme collection";
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:@"share"]) {
NSIndexPath *indexPath = [[self.collectionView indexPathsForSelectedItems] lastObject];
NSManagedObject *object = [[self fetchedResultsController] objectAtIndexPath:indexPath];
SocialViewController *destViewController = segue.destinationViewController;
[destViewController setDetailItem:object];
}
}
#pragma mark - UICollectionView
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
id <NSFetchedResultsSectionInfo> sectionInfo = [self.fetchedResultsController sections][section];
return [sectionInfo numberOfObjects];
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
CollectionViewCell *cell = (CollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier
forIndexPath:indexPath];
NSManagedObject *object = [self.fetchedResultsController objectAtIndexPath:indexPath];
[cell setImage:[UIImage imageWithData:[object valueForKey:@"image"]]];
return cell;
}
#pragma mark - Fetched results controller
- (NSFetchedResultsController *)fetchedResultsController
{
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Edit the entity name as appropriate.
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Meme" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
[fetchRequest setFetchBatchSize:20];
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:@"Master"];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;
NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error]) {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
return _fetchedResultsController;
}
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
{
NSMutableDictionary *change = [NSMutableDictionary new];
switch(type) {
case NSFetchedResultsChangeInsert:
change[@(type)] = @(sectionIndex);
break;
case NSFetchedResultsChangeDelete:
change[@(type)] = @(sectionIndex);
break;
}
[_sectionChanges addObject:change];
}
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath
{
NSMutableDictionary *change = [NSMutableDictionary new];
switch(type)
{
case NSFetchedResultsChangeInsert:
change[@(type)] = newIndexPath;
break;
case NSFetchedResultsChangeDelete:
change[@(type)] = indexPath;
break;
case NSFetchedResultsChangeUpdate:
change[@(type)] = indexPath;
break;
case NSFetchedResultsChangeMove:
change[@(type)] = @[indexPath, newIndexPath];
break;
}
[_objectChanges addObject:change];
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
if ([_sectionChanges count] > 0)
{
[self.collectionView performBatchUpdates:^{
for (NSDictionary *change in _sectionChanges)
{
[change enumerateKeysAndObjectsUsingBlock:^(NSNumber *key, id obj, BOOL *stop) {
NSFetchedResultsChangeType type = [key unsignedIntegerValue];
switch (type)
{
case NSFetchedResultsChangeInsert:
[self.collectionView insertSections:[NSIndexSet indexSetWithIndex:[obj unsignedIntegerValue]]];
break;
case NSFetchedResultsChangeDelete:
[self.collectionView deleteSections:[NSIndexSet indexSetWithIndex:[obj unsignedIntegerValue]]];
break;
case NSFetchedResultsChangeUpdate:
[self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:[obj unsignedIntegerValue]]];
break;
}
}];
}
} completion:nil];
}
if ([_objectChanges count] > 0 && [_sectionChanges count] == 0)
{
[self.collectionView performBatchUpdates:^{
for (NSDictionary *change in _objectChanges)
{
[change enumerateKeysAndObjectsUsingBlock:^(NSNumber *key, id obj, BOOL *stop) {
NSFetchedResultsChangeType type = [key unsignedIntegerValue];
switch (type)
{
case NSFetchedResultsChangeInsert:
[self.collectionView insertItemsAtIndexPaths:@[obj]];
break;
case NSFetchedResultsChangeDelete:
[self.collectionView deleteItemsAtIndexPaths:@[obj]];
break;
case NSFetchedResultsChangeUpdate:
[self.collectionView reloadItemsAtIndexPaths:@[obj]];
break;
case NSFetchedResultsChangeMove:
[self.collectionView moveItemAtIndexPath:obj[0] toIndexPath:obj[1]];
break;
}
}];
}
} completion:nil];
}
[_sectionChanges removeAllObjects];
[_objectChanges removeAllObjects];
}
@end
當我運行,並嘗試訪問該視圖控制器,應用程序崩潰與此錯誤消息: 2013年7月25日23:08:11.832 MemeGen [ 87259:C07] *終止應用程序由於未捕獲的異常「NSInvalidArgumentException」,原因是:「+ entityForName:無不是合法的NSManagedObjectContext參數搜索實體名稱‘梅梅’」 *第一擲調用堆棧:
和它指向這行代碼:
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Meme" inManagedObjectContext:self.managedObjectContext];
顯然self.managedObjectContext爲零。 我應該如何分配它?當用戶首次啓動應用程序並且核心數據爲空時,我應該如何管理它?禁止訪問,只要沒有圖像?
否則,我知道如何將繪製圖像存儲在文件系統上。如果有人知道在UICollectionView中加載它的方法,它也可能是我可以接受的解決方案。
謝謝你的幫助!我發現丟失了什麼,現在存儲的圖像被加載,並且不再崩潰...... 我需要在fetchedResultsController方法中添加這些行: NSSortDescriptor * sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@「image」ascending:NO]; NSArray * sortDescriptors = @ [sortDescriptor]; – lweingart
並添加此方法: - (NSManagedObjectContext *)managedObjectContext { NSManagedObjectContext * context = nil; id delegate = [[UIApplication sharedApplication] delegate]; if([delegate performSelector:@selector(managedObjectContext)]){context = [delegate managedObjectContext]; } return context; } – lweingart