我想實現一個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