Я знаю, что, вероятно, есть очень простое решение. Я использую пример Apple iphoneCoreDataRecipes. Я пытаюсь перейти от исходной таблицы (RecipeTypeTableViewController) типов RecipeTypes (например, напитков, десертов, блюд) к следующему табличному представлению со списком рецептов этого типа (RecipeListTableViewController). Я создал новый класс RecipeType, думая, что могу просто использовать его для возврата рецептов выбранного RecipeType. Пока лучшее, что я могу получить, это разрешить выбор, но он показывает один и тот же список всех рецептов. Исходный код начинается с RecipeListTableViewController, использующего NSFetchedResults для отображения всех рецептов. Теперь у меня есть начальное представление RecipeTypes, но я не уверен, как передать выбранный тип в RecipeListTableViewController. Мне нужно изменить RecipeListTableViewController, чтобы показать список выбранного RecipeType, но я не уверен, как это реализовать. Я думаю, что в основном хочу передать NSMutableArray fetchedresults в другое табличное представление, но не уверен, в каком направлении двигаться. И я не хочу портить другие рабочие действия в RecipeListTableViewController, т.е. поиск и редактирование рецептов. Вот изображения действий таблицы [RecipeTypeTableView][1] и [RecipeListTableview][2]. Заранее благодарим вас за любые предложения.
Удалил эти
Файл: RecipeType.h
Файл: RecipeType.m
Я использую тип NSManagedObject * из моего класса рецептов NSManagedObject для создания начального представления типов рецептов (закусок, блюд и т. д.) в RecipeTypeTableViewController —
Файл: Recipe.h
@interface Recipe : NSManagedObject
@property (nonatomic, strong) NSManagedObject *type;
Файл: RecipeTypeTableViewController.h
// RecipeTypeTableViewController.h
// Recipes
#import <UIKit/UIKit.h>
@interface RecipeTypeTableViewController : UITableViewController <NSFetchedResultsControllerDelegate>
@property (strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, strong) NSManagedObject *type;
@end
Файл: RecipeTypeTableViewController.m — часть подготовки к переходу
#import "RecipeTypeTableViewController.h"
#import "Recipe.h"
#import "RecipeListTableViewController.h"
@interface RecipeTypeTableViewController () <NSFetchedResultsControllerDelegate>
@property (nonatomic, strong) NSFetchedResultsController *fetchedResultsController;
@end
@implementation RecipeTypeTableViewController
static NSString *MyIdentifier = @"showRecipes";
- (void)viewDidLoad {
[super viewDidLoad];
// register this class for our cell to this table view under the specified identifier 'ARecipeType'
self.title = @"Category";
//[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"ARecipeType"];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didChangePreferredContentSize:)name:UIContentSizeCategoryDidChangeNotification object:nil];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
NSError *error = nil;
if (![[self fetchedResultsController] performFetch:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
//abort();
}
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.title = @"Category";
}
- (void)didChangePreferredContentSize:(NSNotification *)notification
{
[self.tableView reloadData];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIContentSizeCategoryDidChangeNotification object:nil];
}
#pragma mark - Table view data source
//- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
//#warning Incomplete implementation, return the number of sections
//return [[self.recipeTypeFetchedResultsController sections] count];
// return 1;
//}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Number of rows is the number of recipe types
id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
return [sectionInfo numberOfObjects];
//return self.recipeTypes.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ARecipeType" forIndexPath:indexPath];
// Configure the cell
NSManagedObject *recipeType = [self.recipeTypes objectAtIndex:indexPath.row];
cell.textLabel.text = [recipeType valueForKey:@"name"];
return cell;
}
#pragma mark - Fetched results controller
- (NSFetchedResultsController *)fetchedResultsController {
// Set up the fetched results controller if needed.
if (_fetchedResultsController == nil) {
// Create the fetch request for the entity.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Edit the entity name as appropriate.
NSEntityDescription *entity = [NSEntityDescription entityForName:@"RecipeType" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
NSLog(@"Setting up a Fetched Results Controller for the Entity named %@", entity);
// Edit the sort key as appropriate.
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
// Edit the section name key path and cache name if appropriate.
// nil for section name key path means "no sections".
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:@"Recipe"];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;
NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error])
{
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
}
}
return _fetchedResultsController;
}
#pragma mark - Navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:@"showRecipes"]) {
NSLog(@"Setting RecipeType for the RecipeListTableViewController");
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
Recipe *selectedType = [self.fetchedResultsController objectAtIndexPath:indexPath];
RecipeListTableViewController *recipeListViewController = segue.destinationViewController;
recipeListViewController.type = selectedType;
recipeListViewController.managedObjectContext = self.managedObjectContext;
}
}
Файл: RecipeListTableViewController.h — часть NSPredicate и кеш FRC
#import <UIKit/UIKit.h>
#import "RecipeAddViewController.h"
@interface RecipeListTableViewController : UITableViewController <RecipeAddDelegate, NSFetchedResultsControllerDelegate>
@property (strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, strong) NSManagedObject *type;
Файл: RecipeListTableViewController.m
#import "RecipeListTableViewController.h"
#import "RecipeDetailViewController.h"
#import "Recipe.h"
#import "RecipeTableViewCell.h"
#import "Recipe+Extensions.h"
#import "TypeSelectionViewController.h"
#import "IngredientDetailViewController.h"
#import "Ingredient.h"
#import "WhereViewController.h"
#import "FavoriteListTableViewController.h"
#import "RecipeTypeTableViewController.h"
#import "RecipeType.h"
@interface RecipeListTableViewController () <NSFetchedResultsControllerDelegate, UISearchBarDelegate, UISearchResultsUpdating>
@property (nonatomic, strong) NSFetchedResultsController *fetchedResultsController;
@property (nonatomic, strong) NSArray *filteredList;
@property (nonatomic, strong) NSFetchRequest *searchFetchRequest;
@property (nonatomic, strong) UISearchController *searchController;
typedef NS_ENUM(NSInteger, RecipesSearchScope)
{
searchScopeRecipe = 0,
searchScopeIngredients = 1
};
@end
@implementation RecipeListTableViewController
#pragma mark - Fetched results controller
- (NSFetchedResultsController *)fetchedResultsController {
// Set up the fetched results controller if needed.
if (_fetchedResultsController == nil) {
// Create the fetch request for the entity.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Edit the entity name as appropriate.
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Recipe" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
[NSFetchedResultsController deleteCacheWithName:@"Recipe"];
// Create predicate
//if (self.type) {
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"type == %@", self.type];
[fetchRequest setPredicate:predicate];
//}
// Edit the sort key as appropriate.
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
// Edit the section name key path and cache name if appropriate.
// nil for section name key path means "no sections".
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:@"Recipe"];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;
NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error])
{
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
}
}
return _fetchedResultsController;
}
/
Когда у меня кеш FRC установлен на «Рецепт». Он падает. Это показало эту подсказку для просмотра кеша CoreData: FATAL ERROR: постоянный кеш информации о разделе не соответствует текущей конфигурации. Вы незаконно изменили запрос выборки NSFetchedResultsController, его предикат или описание сортировки...
Если я установлю кеш на ноль или добавлю [NSFetchedResultsController deleteCacheWithName:@"Recipe"]; до установки предиката все работает так, как ожидалось. У меня есть этот кеш в начальном контроллере представления и втором контроллере представления. Может быть, в этом проблема - мне нужен кеш только в начальном контроллере представления?