2012-11-15 82 views
0

我有一個主/細節的應用程序。
默認情況下,我們將MasterViewController附加到TableViewController,另外,我已將它附加到Sqlite數據庫,並且所有數據都應該正確顯示。所以我添加了一個UISearchBar,以便搜索所有的項目;
搜索功能工作正常,但唯一的錯誤是,搜索欄滾動時消失。
因此,作爲一個解決方案,我刪除了TableViewController並創建了一個簡單的UIVIewController,並添加了一個TableView,TableViewCell和一個搜索欄,以便將搜索欄固定在視圖之上,正如許多人所建議的那樣。
現在,這兩個概念之間的區別在於,TableViewController(第一種情況)在應用程序加載時在單元中加載整個數據,而ViewController(第二種情況,帶有tableView,tableViewCell和searchBar)在啓動時不加載任何內容它在用戶開始在searchBar中寫入單詞時加載不同的元素。如何強制tableView在啓動時加載所有元素,就像如果你有一個TableViewCOntroller一樣?
這是我的代碼:TableViewController Vs UIViewController和

// 
// MasterViewController.m 

#import "MasterViewController.h" 

#import "DetailViewController.h" 
#import <sqlite3.h> 
#import "Author.h" 
@interface MasterViewController() 
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath; 
@end 

@implementation MasterViewController 
NSString *authorNAme , *authorNAme2; 

@synthesize tableView; 
@synthesize searchWasActive; 
@synthesize detailViewController = _detailViewController; 
@synthesize fetchedResultsController = __fetchedResultsController; 
@synthesize managedObjectContext = __managedObjectContext; 
@synthesize theauthors; 
NSString *PathDB; 


-(BOOL)canBecomeFirstResponder{ 

    return YES; 


} 
- (void)awakeFromNib 
{ 
    // self.clearsSelectionOnViewWillAppear = NO; 
    self.contentSizeForViewInPopover = CGSizeMake(320.0, 600.0); 
    [super awakeFromNib]; 
} 

- (void)viewDidLoad 


{ 
    // [self numberOfSectionsInTableView:tableView]; 


    //[self tableView:tableView willDisplayCell:[self.tableView dequeueReusableCellWithIdentifier:@"Cell"] forRowAtIndexPath:0]; 
    //[self.tableView 

    searchBar.delegate = (id)self; 
    // [self.tableView reloadData]; 

    // [self configureCell:@"Cell" atIndexPath:0]; 
    [self authorList]; 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view, typically from a nib. 
    self.navigationItem.leftBarButtonItem = self.editButtonItem; 

    UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(insertNewObject:)]; 
    self.navigationItem.rightBarButtonItem = addButton; 
    self.detailViewController = (DetailViewController *)[[self.splitViewController.viewControllers lastObject] topViewController]; 
} 

- (void)viewDidUnload 
{ 


    [self setTableView:nil]; 
    tableView = nil; 
    searchBar = nil; 
    [self setSearchWasActive:nil]; 
    [super viewDidUnload]; 
    // Release any retained subviews of the main view. 
} 

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{ 
    return YES; 
} 

- (void)insertNewObject:(id)sender 
{ 
    NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext]; 
    NSEntityDescription *entity = [[self.fetchedResultsController fetchRequest] entity]; 
    NSManagedObject *newManagedObject = [NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context]; 

    // If appropriate, configure the new managed object. 
    // Normally you should use accessor methods, but using KVC here avoids the need to add a custom class to the template. 
    [newManagedObject setValue:[NSDate date] forKey:@"timeStamp"]; 

    // Save the context. 
    NSError *error = nil; 
    if (![context save:&error]) { 
     // Replace this implementation with code to handle the error appropriately. 
     // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 
     NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
     abort(); 
    } 
} 




- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar { 
    //[self authorList]; 
    // [filteredTableData release]; 

    //[self.tableView reloadData]; 
    NSLog(@"Cancel Button Clicked"); 

    // Scroll to top 
    [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:YES]; 
    self.searchDisplayController.searchBar.text [email protected]" "; 
} 


- (void) searchBarTextDidBeginEditing:(UISearchBar *)sender 
{ 

    [self.tableView reloadData]; 
    searchBar.showsCancelButton=NO; 

} 


-(void)searchBar:(UISearchBar*)searchBar textDidChange:(NSString*)text 
{ 
    searchBar.showsCancelButton=NO; 
    if(text.length == 0) 
    { 
     isFiltered = FALSE; 

    } 
    else 
    { 
     isFiltered = true; 
     filteredTableData = [[NSMutableArray alloc] init]; 

     for (Author* author in theauthors) 

     { //[NSPredicate predicateWithFormat:@"SELECT * from books where title LIKE %@", searchBar.text]; 

      NSRange nameRange = [author.name rangeOfString:text options:NSAnchoredSearch]; 
      NSRange descriptionRange = [author.genre rangeOfString:text options:NSAnchoredSearch]; 
      if(nameRange.location != NSNotFound || descriptionRange.location != NSNotFound) 
      { 
       [filteredTableData addObject:author]; 
       NSLog(@"Item Added is %@" , author.name); 

      } 
     } 
    } 

    [self.tableView reloadData]; 

} 





#pragma mark - Table View methods 

-(NSMutableArray *) authorList{ 
    [self numberOfSectionsInTableView:tableView]; 
    theauthors = [[NSMutableArray alloc] initWithCapacity:1000000]; 
    // NSMutableArray * new2 = [[NSMutableArray alloc ] initWithCapacity:100000]; 
    // authorNAme = theauthors.sortedArrayHint.description; 
    @try { 
     NSFileManager *fileMgr = [NSFileManager defaultManager]; 
     NSLog(@"Before the dbpath variable"); 
     NSString *dbPath = [[[NSBundle mainBundle] resourcePath ]stringByAppendingPathComponent:@"dictionary_native.sqlite"]; 
     NSLog(@"After the dbpath variable"); 
     BOOL success = [fileMgr fileExistsAtPath:dbPath]; 
     if(!success) 

     { 
      NSLog(@"1"); 
      NSLog(@"Cannot locate database file '%@'.", dbPath); 
     } 
     NSLog(@"Database correctly located"); 
     if(!(sqlite3_open([dbPath UTF8String], &db) == SQLITE_OK)) 
     { 
      NSLog(@"2"); 
      NSLog(@"An error has occured: %@", sqlite3_errmsg(db)); 

     } 
     NSLog(@"Database correctly opened"); 

     // const char *sql = "SELECT F_Keyword FROM wordss"; 
     const char *sql = "SELECT * FROM wordss"; 

     sqlite3_stmt *sqlStatement; 
     if(sqlite3_prepare(db, sql, -1, &sqlStatement, NULL) != SQLITE_OK) 
     { 
      NSLog(@"Problem with prepare statement: %@", sqlite3_errmsg(db)); 
     }else{ 
      while (sqlite3_step(sqlStatement)==SQLITE_ROW) { 
       // NSLog(@"entered the while statement"); 
       Author * author = [[Author alloc] init]; 

//    // NSLog(@"Author initialised"); 
//     
       author.name = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement,1)]; 
       // NSLog(@"this is the author.name %@" , author.name); 
       author.genre = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement, 2)]; 
//     
       // authorNAme=author.genre;    
//     

       [theauthors addObject:author]; 




      } 
      //  authorNAme = author.genre; 


     } 
    } 
    @catch (NSException *exception) { 
     NSLog(@"Problem with prepare statement: %@", sqlite3_errmsg(db)); 
    } 
    @finally { 
     // sqlite3_finalize(sqlStatement);. 
     // authorNAme = nil; 

     // authorNAme = Nil; 
     return theauthors; 
    } 


} 





- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
{ 

    // return [[self.fetchedResultsController sections] count]; 

    return 1; 

} 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 
// id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section]; 
// return [sectionInfo numberOfObjects]; 

    int rowCount; 
    if(self->isFiltered) 
     rowCount = filteredTableData.count; 
    else 
     rowCount = theauthors.count; 
    NSLog(@"This is the number of rows accepted %i" , rowCount); 
    return rowCount; 

} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    // UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:@"Cell"]; 

    static NSString *CellIdentifier = @"Cell"; 

    UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 


    if (cell == nil) { 
     cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]; 
    } 
    int rowCount = indexPath.row; 

    Author *author = [self.theauthors objectAtIndex:rowCount]; 


    if(isFiltered){ 
     author = [filteredTableData objectAtIndex:indexPath.row];   

    } 
    else{ 
     author = [theauthors objectAtIndex:indexPath.row];  
    } 

    cell.textLabel.text = author.name; 


    return cell; 
} 

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    // Return NO if you do not want the specified item to be editable. 
    return YES; 
} 

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    if (editingStyle == UITableViewCellEditingStyleDelete) { 
     NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext]; 
     [context deleteObject:[self.fetchedResultsController objectAtIndexPath:indexPath]]; 

     NSError *error = nil; 
     if (![context save:&error]) { 
      // Replace this implementation with code to handle the error appropriately. 
      // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 
      NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
      abort(); 
     } 
    } 
} 

- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    // The table view should not be re-orderable. 
    return NO; 
} 

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
// NSManagedObject *object = [[self fetchedResultsController] objectAtIndexPath:indexPath]; 
// self.detailViewController.detailItem = object; 


    // DetailViewController* vc ; 
    MasterViewController *author; 
    NSLog(@"This is the showDetailsForIndexPath"); 
    [self->searchBar resignFirstResponder]; 
    // Details* vc = [self.storyboard instantiateViewControllerWithIdentifier:@"Details"]; 
    // AuthorVC* author; 

    if(isFiltered) 
    { 
     author = [filteredTableData objectAtIndex:indexPath.row]; 
    } 
    else 
    { 
     author = [theauthors objectAtIndex:indexPath.row]; 
    } 

    //vc.author = author; 
    authorNAme = author.genre; 
    authorNAme2 = author.name ; 


    // author = [theauthors objectAtIndex:indexPath.row]; 

    NSLog(@"This is the author.genre %@" , author.genre); 

    //vc.author.genre = author.genre; 
    authorNAme = author.genre; 
    authorNAme2 = author.name; 

    //NSLog(@"This is the details %@",vc.author.genre); 
    NSLog(@"This is the authorNAme Variable %@" , authorNAme); 

    self.detailViewController.detailItem = authorNAme; 
    self.detailViewController.detailItem2 = authorNAme2; 

} 

#pragma mark - Fetched results controller 

- (NSFetchedResultsController *)fetchedResultsController 
{ 
    if (__fetchedResultsController != nil) { 
     return __fetchedResultsController; 
    } 

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
    // Edit the entity name as appropriate. 
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:self.managedObjectContext]; 
    [fetchRequest setEntity:entity]; 

    // Set the batch size to a suitable number. 
    [fetchRequest setFetchBatchSize:20]; 

    // Edit the sort key as appropriate. 
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"timeStamp" ascending:NO]; 
    NSArray *sortDescriptors = [NSArray arrayWithObjects: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:@"Master"]; 
    aFetchedResultsController.delegate = self; 
    self.fetchedResultsController = aFetchedResultsController; 

    NSError *error = nil; 
    if (![self.fetchedResultsController performFetch:&error]) { 
     // Replace this implementation with code to handle the error appropriately. 
     // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 
     NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
     abort(); 
    } 

    return __fetchedResultsController; 
}  

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller 
{ 
    [self.tableView beginUpdates]; 
} 

- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo 
      atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type 
{ 
    switch(type) { 
     case NSFetchedResultsChangeInsert: 
      [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade]; 
      break; 

     case NSFetchedResultsChangeDelete: 
      [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade]; 
      break; 
    } 
} 

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject 
     atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type 
     newIndexPath:(NSIndexPath *)newIndexPath 
{ 
    // UITableView *tableView = self.tableView; 

    switch(type) { 
     case NSFetchedResultsChangeInsert: 
      [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade]; 
      break; 

     case NSFetchedResultsChangeDelete: 
      [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
      break; 

     case NSFetchedResultsChangeUpdate: 
      [self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath]; 
      break; 

     case NSFetchedResultsChangeMove: 
      [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
      [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]withRowAnimation:UITableViewRowAnimationFade]; 
      break; 
    } 
} 

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller 
{ 
    [self.tableView endUpdates]; 
} 

/* 
// Implementing the above methods to update the table view in response to individual changes may have performance implications if a large number of changes are made simultaneously. If this proves to be an issue, you can instead just implement controllerDidChangeContent: which notifies the delegate that all section and object changes have been processed. 

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller 
{ 
    // In the simplest, most efficient, case, reload the table view. 
    [self.tableView reloadData]; 
} 
*/ 

- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath 
{ 




// NSManagedObject *object = [self.fetchedResultsController objectAtIndexPath:indexPath]; 
// cell.textLabel.text = [[object valueForKey:@"timeStamp"] description]; 
} 

@end 

任何幫助將不勝感激...感謝您抽出寶貴的時間。

+0

你是否檢查委託和數據源方法是否正在調用ie)numberOfRowsInSection,cellForRowAtIndexPath? –

+0

我該如何檢查? –

+0

我是一個新手,這就是爲什麼我可能會問愚蠢的問題,但我很感激,如果你嘗試幫助 –

回答

1

如果tableview在xib鏈接中,它可以更正對象並設置委託和數據源。

+0

謝謝你的解決方案:D –

+0

很高興幫助@EliasRahme –

相關問題