2013-08-04 1 views
1

У меня есть приложение с UICollectionView, представление отображает пользовательские UICollectionViewCells. Когда одна из этих ячеек регистрирует краны, она открывает подробный вид в виде контроллера представления модели. Представление коллекции заполняются данными из основных данных, это выглядит следующим образом:UICollectionview перезагружает данные после сохранения объекта с данными ядра

#pragma mark - Get Items From CoreData 
-(NSArray*)refreshTableData 
{ 



NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Produkt" 
              inManagedObjectContext:context]; 
[fetchRequest setEntity:entity]; 
NSError* error; 
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error]; 

/*for (Produkt *produkt in fetchedObjects) 
{ 
    NSLog(@"Name: %@", produkt.name); 
}*/ 

return fetchedObjects; 
} 

#pragma mark - UICollectionView Datasource 
- (NSInteger)collectionView:(UICollectionView *)view numberOfItemsInSection: (NSInteger)section { 
return [[self refreshTableData] count]; 
} 

- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath { 
CollectionViewCell* cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"ItemCell" forIndexPath:indexPath]; 

Produkt* produkt = [[self refreshTableData]objectAtIndex:indexPath.row]; 

[cell.collectionLabel setText:produkt.name]; 
[cell.collectionImage setImage:[[UIImage alloc]initWithData:produkt.image]]; 

[cell.layer setCornerRadius:10]; 
[cell.layer setMasksToBounds:YES]; 

CAGradientLayer *gradient = [CAGradientLayer layer]; 
gradient.frame = cell.bounds; 
gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor blackColor] CGColor], (id)[[UIColor whiteColor] CGColor], nil]; 
[cell.layer insertSublayer:gradient atIndex:0]; 

return cell; 
} 

#pragma mark UICollectionViewDelegate 
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath 
{ 

Produkt* produkt = [[self refreshTableData]objectAtIndex:indexPath.row]; 
produktView = [[ProduktViewController alloc] 
       initWithNibName:@"ProduktViewController" 
       bundle:nil]; 



produktView.modalPresentationStyle = UIModalPresentationFormSheet; 
produktView.delegate = self; 
produktView.produkt = produkt; 

[self presentViewController:produktView animated:YES completion:nil]; 
} 

- (UIEdgeInsets)collectionView: 
(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section { 
return UIEdgeInsetsMake(50, 20, 50, 20); 
} 

Когда я создаю новый Produkt Object (NSManagedObject), сохраните его и перезагрузите UICollectionView все работает отлично. То код для создания нового Produkt-Object:

-(void)selectedItem:(NSString *)selectedItem 
{ 
//Dismiss the popover if it's showing. 
if (itemPickerPopover) { 
    [itemPickerPopover dismissPopoverAnimated:YES]; 
    itemPickerPopover = nil; 
} 

if([selectedItem isEqualToString:@"Produkt"]) 
{ 
    NSLog(@"SELECTED ITEM:%@",selectedItem); 
    produktView = [[ProduktViewController alloc] 
         initWithNibName:@"ProduktViewController" 
         bundle:nil]; 
    Produkt* newProdukt = [NSEntityDescription 
          insertNewObjectForEntityForName:@"Produkt" 
          inManagedObjectContext:context]; 

    produktView.modalPresentationStyle = UIModalPresentationFormSheet; 
    produktView.delegate = self; 
    produktView.context = context; 
    produktView.produkt = newProdukt; 

    [self presentViewController:produktView animated:YES completion:nil]; 
} 

} 

Теперь, когда я выбираю ячейку и детализированный вид всплывает, и я редактировать данные в подробном представлении, а затем сохранить его, с помощью этой функции (содержится в классе зрения подробно):

-(void)saveChanges 
{ 
     NSLog(@"SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE SAVE "); 

    produkt.name = name.text; 
    produkt.artikelNr = artikelNr.text; 
    produkt.gekauftBei = bestelltBei.text; 
    produkt.gebrauchsAnweisung = gebrauchsAnleitung.text; 

    NSData *savedImageData = UIImagePNGRepresentation(image.image); 
    produkt.image = savedImageData; 

    NSError *error; 
    [context save:&error]; 

    } 

Когда контроллер подробно отклоняет эту функцию делегат вызывается:

#pragma mark ProduktView delegate 
-(void)didDismissPresentedViewController 
{ 
NSLog(@"DISMISS CONTROLLER"); 
[produktView dismissViewControllerAnimated:YES completion:nil]; 

[collectionView reloadData]; 
} 

Теперь здесь возникает проблема: Когда я сохранить измененный объект и г eload представление таблицы, представленные ячейки связаны с неправильными объектами. Например, в представлении коллекции показаны объекты: 1, 2, 3, 4, но когда я нажимаю, например, на объект 3, детальный вид показывает объект 1. После того как я отклонил контроллер вида, вид коллекции снова изменит порядок. Когда я перезапущу приложение, изменения, которые я сделал для объекта, не сохраняются.

В главном контроллере представления я создал один NSMangedObjectContext, который передаю другим контроллерам, поэтому я всегда остаюсь в том же контексте.

AppDelegate *appDelegate = 
[[UIApplication sharedApplication] delegate]; 
context = 
[appDelegate managedObjectContext]; 

Благодарим за помощь.

ответ

2

Без дескриптора сортировки порядок объектов, возвращаемых запросом выборки, равен undefined. Даже не гарантировано, что два идентичных запроса на выборку возвращают объекты в том же порядке.

Поскольку все ваши методы источника данных коллекции выполнить новый запрос выборки (который является крайне неэффективным!) Ничего не может сказать о том, какой объект

Produkt* produkt = [[self refreshTableData]objectAtIndex:indexPath.row]; 

в cellForItemAtIndexPath фактически возвращает.

Таким образом, одним из возможных решений было бы получить объекты один раз в NSArray и использовать этот массив в качестве источника данных просмотра коллекций. Если объект был добавлен или изменен, выполните новый запрос на выборку и перезагрузите представление коллекции.

Другим возможным решением могло бы стать использование NSFetchedResultsController (FRC). FRC автоматически отслеживает изменения в контексте управляемого объекта и вызывает функции делегата , если объекты вставлены, удалены или изменены. Если вы выберете путь , вы должны заметить, что использование FRC с видом коллекции немного сложнее , чем с табличным представлением, насколько это касается автоматических анимированных обновлений. Но эта статья http://ashfurrow.com/blog/uicollectionview-example может помочь.

+0

Большое спасибо, с помощью вашего совета я решил свою проблему :) –

+0

@ jonajürgen: Добро пожаловать! –