2012-04-17 63 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呈現。