TableViewController与UIViewController和一个tableView里面

时间:2012-11-15 10:37:45

标签: xcode uitableview xcode4.3

我有一个Master / Details应用程序。
默认情况下,我们将MasterViewController附加到TableViewController,此外,我已将它附加到Sqlite数据库,并且所有数据都正确显示。所以我添加了一个UISearchBar,以便搜索所有项目;
搜索功能正常,但唯一的错误是,向下滚动时搜索栏消失。
作为解决方案,我删除了TableViewController并创建了一个简单的UIVIewController并添加了一个TableView, TableViewCell和一个搜索栏,以便按照许多人的建议将搜索栏固定在View的顶部。
现在这两个概念的区别在于,TableViewController(First Case)将整个数据加载到单元格中一旦应用程序加载,当ViewController(第二个案例,带有tableView,tableViewCell和searchBar)在启动时没有加载任何内容时,它会在用户开始在searchBar中编写单词时加载不同的元素。如何强制tableView在启动时加载所有元素,就像你有一个TableViewCOntroller一样? 这是我的代码:

//
//  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 =@" ";
}


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

任何帮助将受到高度赞赏...感谢您抽出宝贵时间。

1 个答案:

答案 0 :(得分:1)

如果tableview在xib中链接到正确的对象并设置委托和数据源。