开发者

Selected row in UITableView shows a different result in the next TabBarViewController

开发者 https://www.devze.com 2023-02-05 20:31 出处:网络
I have been trying to figure out what went wrong with this segment in my code. It was working fine for a normal UITableView, which has data extracted from a local database (results after clicking a bu

I have been trying to figure out what went wrong with this segment in my code. It was working fine for a normal UITableView, which has data extracted from a local database (results after clicking a button).

However, after I used this similar code for a UITableView that shows results of a search (I was trying to do a multiple category search but failed), there has been errors, differences between the selected row and the outcome or results on the TabBarViewController.

Following is my code for the linkage to the TabBarViewController.

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

     UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];



     [self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];



     TabBarViewController *tabBarView = [[TabBarViewController alloc] initWithNibName:@"TabBarViewController" bundle:[NSBundle mainBundle]];

     Attraction *att = [attractions objectAtIndex: indexPath.row];


     tabBarView.attraction = att; 

     [self.navigationController presentModalViewController:tabBarView animated:YES];
     [tableView deselectRowAtIndexPath:indexPath animated:YES];
     [tabBarView release];

    }

Here are my full codes for you to inspect:

-(void) checkAndCreateDatabase{

    // Check if the SQL database has already been saved to the users phone, if not then copy it over
    databaseName = @"funsg.sql";

    // Get the path to the documents directory and append the databaseName
    NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDir = [documentPaths objectAtIndex:0];

    databasePath = [documentsDir stringByAppendingPathComponent:databaseName];
    //NSLog([NSString stringWithFormat:@"GetData %@", databasePath]);
    BOOL success;

    // Create a FileManager object, we will use this to check the status
    // of the database and to copy it over if required
    NSFileManager *fileManager = [NSFileManager defaultManager];

    // Check if the database has already been created in the users filesystem
    success = [fileManager fileExistsAtPath:databasePath];

    NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:databaseName]; 
    // Copy the database from the package to the users filesystem
    [fileManager copyItemAtPath:databasePathFromApp toPath:databasePath error:nil];
    [fileManager release];

}

-(void)createEditableCopyOfDatabaseIfNeeded {

    BOOL success;
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSError *error;
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:@"abc.sql"];
    success = [fileManager fileExistsAtPath:writableDBPath];
    if (success) return;
    // The writable database does not exist, so copy the default to the appropriate location.
    NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"abc.sql"];
    success = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error];
    if (!success) {
        NSAssert1(0, @"Failed to create writable database file with message '%@'.", [error localizedDescription]);
    }
}

-(void) readAttractionsFromDatabase {
    [self checkAndCreateDatabase];


    // Open the database
    if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
        // Setup the SQL Statement and compile it for faster access
        const char *sqlStatement = [[NSString stringWithFormat:@"select * from everything "] UTF8String];
        //NSLog([NSString stringWithFormat:@"select * from everything"]);

        sqlite3_stmt *compiledStatement;
        if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
            // Loop through the results and add them to the feeds array
            while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
                // Read the data from the result row
                NSString *bus       = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 0)];
                NSString *desc      = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
                NSString *location  = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)];
                NSString *mrt       = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 3)];
                NSString *name      = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 4)];
                NSString *image     = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 5)];
                NSString *type      = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 6)];
                NSString *carpark   = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 7)];

                // Create a new animal object with the data from the database
                Attraction *att = [[Attraction alloc] initWithName:desc buses:bus add:location type:type mrt:mrt image:image name:name carpark:carpark];

                if (attractions == NULL)
                    // There should not be a NULL name
                    NSLog(@"Null name!!");
                else {

                    [attractions addObject:att];
                    // Apparently the addObject function in NSMutableArray does not
                    // keep a copy of our object, so, we can't release it.
                    //[name release];
                    [att release];
                }
            }
            sqlite3_finalize(compiledStatement); // Cleanup the statement
        }
        else {
            NSLog(@"Error retrieving data from database.");
        }
        sqlite3_close(database);
    }
    else {
        NSLog(@"Error: Can't open database!");
    }
}
-(void)viewDidLoad {
    [super viewDidLoad];
    attractions = [[NSMutableArray alloc] init];
    searchedNames = [[NSMutableArray alloc] init];
    [self loadData];

}

-(void) insertToDB :(Attraction*) att {
    [self checkAndCreateDatabase];

    if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
        static sqlite3_stmt *compiledStatement;
        sqlite3_exec(database, [[NSString stringWithFormat:@"INSERT INTO everything (Bus,Description,Location,MRT,Name,image,type,Carpark) SELECT '%@','%@','%@','%@', '%@', '%@', '%@', '%@' WHERE NOT EXISTS (SELECT 1 FROM everything WHERE Name = '%@');", att.buses,att.desc,att.add, att.mrt, att.name, att.image, att.type , att.carpark,att.name] UTF8String], NULL, NULL, NULL);
        sqlite3_finalize(compiledStatement);

    }
    sqlite3_close(database);    
}

-(void) loadData {
    //First fetch the data from the JSON 
    NSURL *url = nil;

    NSString *querystring = [NSString stringWithFormat:@"http://mp15.bitproj1.com/testsearch.php"];
    url = [NSURL URLWithString:querystring];


    NSString *jsonreturn = [[NSString alloc] initWithContentsOfURL:url];

    //NSLog(@"jsonreturn"); // Look at the console and you can see what the restults are

    NSData *jsonData = [jsonreturn dataUsingEncoding:NSUTF32BigEndianStringEncoding];
    NSError *error = nil;

    // In "real" code you should surround this with try and catch
    self.data = [[CJSONDeserializer deserializer] deserializeAsDictionary:jsonData error:&error];
    if (data==nil){

        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"No Internet Connection" message:@"Unable to update the data."  delegate:self cancelButtonTitle:@"OK" otherButtonTitles: nil];
        [alert show];   
        [alert release];
    }       

    else
    {
        self.rows =[data objectForKey:@"attractions"];

        for (int i=0; i<[self.rows count]; i++) {
            NSDictionary *dict = [rows objectAtIndex: i];
            Attraction* a = [[Attraction alloc] initWithName:[dict objectForKey:@"Description"] 
                                                       buses:[dict objectForKey:@"Bus"]
                       开发者_Python百科                                  add:[dict objectForKey:@"Location"] 
                                                        type:[dict objectForKey:@"type"] 
                                                         mrt:[dict objectForKey:@"MRT"] 
                                                       image:[dict objectForKey:@"image"] 
                                                        name:[dict objectForKey:@"Name"]
                                                     carpark:[dict objectForKey:@"Carpark"]];   

            //Here we insert the data, when inserting we check for the duplicates. If the record already exists we do not insert. Code also must be optimized later
            [self insertToDB:a];
        }
    }


    [jsonreturn release];

    [self readAttractionsFromDatabase];
}



-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return(1);
}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return([searchedNames count]);
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }


    NSString *cellText = [searchedNames objectAtIndex:indexPath.row];
    [cell.textLabel setText:cellText];
    return cell;
}

-(void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar {
}

-(void)searchBarTextDidEndEditing:(UISearchBar *)searchBar {
}

-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {

    [searchedNames removeAllObjects];// remove all data that belongs to previous search
    if([searchText isEqualToString:@""] || searchText==nil) {
        // Nothing to search, empty result.
        [myTableView reloadData];
        return;
    }

    for (NSString *att in attractions) {
        Attraction* p = ((Attraction *)att);
        NSRange r = [p.name rangeOfString:searchText options:NSCaseInsensitiveSearch];
        if(r.location != NSNotFound) {
            [searchedNames addObject:p.name];
        }
    }
    [myTableView reloadData];   
}

-(void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
}

-(void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
    [searchBar resignFirstResponder];
}

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];



    [self.tableView deselectRowAtIndexPath:indexPath animated:YES];



    TabBarViewController *tabBarView = [[TabBarViewController alloc] initWithNibName:@"TabBarViewController" bundle:[NSBundle mainBundle]];

    Attraction *att = [attractions objectAtIndex: indexPath.row];


    tabBarView.attraction = att;    

    [self.navigationController presentModalViewController:tabBarView animated:YES];
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    [tabBarView release];

}
-(void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];
}

-(void)viewDidUnload {

}

-(void)dealloc {
    [data release];
    [attractions release];
    [super dealloc];

}


@end


Are you using two different array as datasource? If so, I think you are not retrieving the value from the correct array.

And also I can't understand the use of this code:

[self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];

You can change that code as:

[self.tableView deselectRowAtIndexPath:indexPath animated:YES];

Edit

You are using two diff arrays searchedNames, attractions. There is the problem:

if(searching==YES)

{

//retrieve the values from searchedNames array

}

else

{

//retrieve the values from attractions array

}


-(void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar {
searching=YES;
}

-(void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
searching=NO;
}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    if(searching==YES)
       return([searchedNames count]);
    else
       return [attractions count];
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }
  NSString *cellText;
    if(searching==YES)
      cellText = [searchedNames objectAtIndex:indexPath.row];
    else
      cellText = [attractions objectAtIndex:indexPath.row];
    [cell.textLabel setText:cellText];
    return cell;
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号