2012-04-17 103 views
0

我想实现一个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 

感谢

回答

1

尝试改变UITableViewControllerUITableView

UITableView  *sectionsTable; 

,使你的类型一UIViewControllerUITableViewController

@interface ChecklistViewController : UITableViewController <NSFetchedResultsControllerDelegate, 
                UITableViewDelegate, 
                UITableViewDataSource> 
+0

我试着让ViewController成为一个UITableViewController,但得到一个'NSInternalInconsistencyException',原因是“[UITableViewController loadView]加载了”ChecklistViewController“的笔尖,但没有得到一个UITableView.'然后它预期NIB是一个 – econstantin 2012-04-17 15:37:49

+0

I尝试使ViewController成为UITableViewController,但在运行时得到'NSInternalInconsistencyException',原因是'[UITableViewController loadView]加载了“ChecklistViewController”nib,但没有得到UITableView。由于该视图将包含多个表以及其他视图/控制器;我认为它需要是一个UIViewController。是否有任何调试选项可以记录iOS在调用委托方法时正在做什么? – econstantin 2012-04-17 15:52:34

+0

不知道那里有两个tableviews,还没有尝试过它自己,但例如有这样的问题在SO这个问题:http://stackoverflow.com/questions/6519673/ios-tableview-delegate-methods-for-two-的tableview – Pfitz 2012-04-17 16:32:24

0

我发现了问题 - 没有正确地被添加到视图中的UITableViewController等级

而不是

- (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;  

应该

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    //Setup tableviews 
    self.sectionsTable = [[UITableViewController alloc] init];  
    [self.sectionsView addSubview:self.sectionsTable.view]; 
    self.sectionsTable.tableView.dataSource = self;   
    self.sectionsTable.tableView.delegate = self;  

注:为sectionsTable.view框架仍然需要进行设置。

tableview和FRC委托方法现在正在调用和tableview呈现。