我想实现一个UIViewController有2 UITableViews(在iPad上):一个显示一个清单的部分,另一个显示所选内容/部分内的问题。UITableView和NSFetchedController委托从来没有叫
我已经设置NSFetchedResultsController,我能够成功地从持久存储中获取对象,但是没有任何一个NSFetchedResultsController或UITableView委托方法被调用。
我确实设置了类以实现各自的协议,并将FRC和TableView委托设置为“self”。
我已经在每个委托方法中放入了断点,但从未到达其中任何一个(是的,我正在运行断点启用并且可以单步执行代码的其他部分)。
我理解,为什么委托方法不会在这些情况下被称为提供任何见解: 1)当[FRC performFetch]执行并FRC.fetchedObjects设定/更新 2)当[的tableView reloadData]是所谓的(至少应该检查numberOfSectionsInTableView)
.h文件中:
#import <UIKit/UIKit.h>
#import <CoreData/CoreData.h>
@interface ChecklistViewController : UIViewController <NSFetchedResultsControllerDelegate,
UITableViewDelegate,
UITableViewDataSource>
{
UIView *sectionsView;
UITableViewController *sectionsTable;
NSFetchedResultsController *sectionsFetchedResultsController;
}
@property (nonatomic, retain) IBOutlet UIView *sectionsView;
@property (nonatomic, retain) IBOutlet UITableViewController *sectionsTable;
@property (nonatomic, retain) NSFetchedResultsController *sectionsFetchedResultsController;
-(void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath;
@end
.m文件
#import "ChecklistViewController.h"
#import "Inspection.h"
#import "InspectionQuestion.h"
#import "ContextManager.h"
@implementation ChecklistViewController
@synthesize sectionsView;
@synthesize sectionsTable;
@synthesize sectionsFetchedResultsController;
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
//Setup tableviews
self.sectionsTable = [[UITableViewController alloc] init];
self.sectionsTable.view = self.sectionsView;
self.sectionsTable.tableView.dataSource = self;
self.sectionsTable.tableView.delegate = self;
//Fetch sections
NSError *error = nil;
if (self.sectionsFetchedResultsController.fetchedObjects == nil) {
self.sectionsFetchedResultsController.delegate = self;
if (![[self sectionsFetchedResultsController] performFetch:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
}
NSLog(@"fetched results:%@",self.sectionsFetchedResultsController.fetchedObjects);
//For testing delegates
[self.sectionsTable.tableView reloadData];
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return YES;
}
#pragma mark -
#pragma mark TableViewDelegate methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
NSInteger count = [[self.sectionsFetchedResultsController sections] count];
if (count == 0) {
count = 1;
}
return count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSInteger numberOfRows = 0;
if ([[self.sectionsFetchedResultsController sections] count] > 0) {
id <NSFetchedResultsSectionInfo> sectionInfo = [[self.sectionsFetchedResultsController sections] objectAtIndex:section];
numberOfRows = [sectionInfo numberOfObjects];
}
NSLog(@"CheckListViewController::numberOfRowsInSection - numberOfRows:%d", numberOfRows);
return numberOfRows;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// Dequeue or if necessary create a TableViewCell, then set its to the for the current row.
static NSString *cellIdentifier = @"cellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
[self configureCell:cell atIndexPath:indexPath];
return cell;
}
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
// Configure the cell
NSLog(@"CheckListViewController::configureCell - indexPath:%@,", indexPath);
InspectionQuestion *question = [self.sectionsFetchedResultsController objectAtIndexPath:indexPath];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"CheckListViewController::didSelectRowAtIndexPath - started");
InspectionQuestion *question = [self.sectionsFetchedResultsController objectAtIndexPath:indexPath];
//[self show: animated:YES];
NSLog(@"CheckListViewController::didSelectRowAtIndexPath - ended");
}
#pragma mark -
#pragma mark FetchedResultsController
- (NSFetchedResultsController *)sectionsFetchedResultsController {
// Set up the fetched results controller if needed.
NSLog(@"ChecklistViewController::sectionsFetchedResultsController - started");
if (sectionsFetchedResultsController == nil) {
NSLog(@"ChecklistViewController::fetchedResultsController - FETCHING new results");
NSManagedObjectContext *managedObjectContext = [[ContextManager sharedContext] managedObjectContext];
// Create the fetch request for the entity.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"InspectionQuestion" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"sectionId" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:nil
cacheName:nil
// cacheName:@"Root"
];
//aFetchedResultsController.delegate = self;
self.sectionsFetchedResultsController = aFetchedResultsController;
// self.sectionsFetchedResultsController.delegate = self;
/* ARC
[aFetchedResultsController release];
[fetchRequest release];
[sortDescriptor release];
[sortDescriptors release];
*/
}
return sectionsFetchedResultsController;
}
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
// The fetch controller is about to start sending change notifications, so prepare the table view for updates.
if (controller == self.sectionsFetchedResultsController) {
[self.sectionsTable.tableView beginUpdates];
}
}
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
UITableView *tableView;
if (controller == self.sectionsFetchedResultsController) {
tableView = self.sectionsTable.tableView;
}
switch(type) {
case NSFetchedResultsChangeInsert:
NSLog(@"ChecklistViewController::didChangeObject - INSERT");
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
NSLog(@"ChecklistViewController::didChangeObject - DELETE");
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
NSLog(@"ChecklistViewController::didChangeObject - UPDATE");
[self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
break;
case NSFetchedResultsChangeMove:
NSLog(@"ChecklistViewController::didChangeObject - MOVE");
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {
switch(type) {
case NSFetchedResultsChangeInsert:
[self.sectionsTable.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[self.sectionsTable.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
// The fetch controller has sent all current change notifications, so tell the table view to process all updates.
[self.sectionsTable.tableView endUpdates];
}
@end
感谢
我试着让ViewController成为一个UITableViewController,但得到一个'NSInternalInconsistencyException',原因是“[UITableViewController loadView]加载了”ChecklistViewController“的笔尖,但没有得到一个UITableView.'然后它预期NIB是一个 – econstantin 2012-04-17 15:37:49
I尝试使ViewController成为UITableViewController,但在运行时得到'NSInternalInconsistencyException',原因是'[UITableViewController loadView]加载了“ChecklistViewController”nib,但没有得到UITableView。由于该视图将包含多个表以及其他视图/控制器;我认为它需要是一个UIViewController。是否有任何调试选项可以记录iOS在调用委托方法时正在做什么? – econstantin 2012-04-17 15:52:34
不知道那里有两个tableviews,还没有尝试过它自己,但例如有这样的问题在SO这个问题:http://stackoverflow.com/questions/6519673/ios-tableview-delegate-methods-for-two-的tableview – Pfitz 2012-04-17 16:32:24