Push different views from a table
I've been following a tutorial to implement a search bar.
However I can't seem to push different views. Here is what my didsSelectRowAtIndexPath looks like.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *selectedCountry = nil;
if(searching)
selectedCountry = [copyListOfItems objectAtIndex:indexPath.row];
else {
NSDictionary *dictionary = [listOfItems objectAtIndex:indexPath.section];
NSArray *array = [dictionary objectForKey:@"Countries"];
selectedCountry = [array objectAtIndex:indexPath.row];
}
//Initialize the detail view controller and display it.
if ([[listOfItems objectAtIndex:indexPath.row] isEqual:@"neon"]){
Neon *abo = [[Neon alloc] initWithNibName:@"Neon" bundle:nil];
//dvController.selectedCountry = selectedCountry;
[self.navigationController pushViewController:abo animated:YES];
[abo release];
}
}
And here is the debuger message when I click on neon: 2010-05-09 08:47:27.516 iTeachU[3821:307] * Terminating app due to uncaught exception 'NSRangeException', reason: '* -[NSMutableArray objectAtIndex:]: index 60 beyond bounds [0 .. 0]' *** Call stack at first throw: terminate called after throwing an instance of 'NSException' Program received signal: “SIGABRT”.
If anyone has a way to push views based on the cells text it would be greatly appreciated. Thanks
Edit Entire .m
- (void)viewDidLoad {
[super viewDidLoad];
listOfItems = [[NSMutableArray alloc] init];
NSArray *ElementsArray = [NSArray arrayWithObjects:@"Actinium",
@"Aluminium",
@"Americium",
@"Antimony",
@"Argon",
@"Arsenic",
@"Astatine",
@"Barium",
@"Berkelium",
@"Beryllium",
@"Bismuth",
@"Bohrium",
@"Boron",
@"Bromine",
@"Cadmium",
@"Cesium",
@"Calcium",
@"Californium",
@"Carbon",
@"Cerium",
@"Chlorine",
@"Chromium",
@"Cobalt",
@"Copper",
@"Curium",
@"Darmstadtium",
@"Dubnium",
@"Dysprosium",
@"Einsteinium",
@"Erbium",
@"Europium",
@"Fermium",
@"Fluorine",
@"Francium",
@"Gadolinium",
@"Gallium",
@"Germanium",
开发者_开发知识库 @"Gold",
@"Hafnium",
@"Hassium",
@"Helium",
@"Holmium",
@"Hydrogen",
@"Indium",
@"Iodine",
@"Iridium",
@"Iron",
@"Krypton",
@"Lanthanum",
@"Lawrencium",
@"Lead",
@"Lithium",
@"Lutetium",
@"Magnesium",
@"Manganese",
@"Meitnerium",
@"Mendelevium",
@"Mercury",
@"Molybdenum",
@"Neodymium",
@"neon",
@"Neptunium",
@"Nickel",
@"Niobium",
@"Nitrogen",
@"Nobelium",
@"Osmium",
@"Oxygen",
@"Palladium",
@"Phosphorus",
@"Platinum",
@"Plutonium",
@"Polonium",
@"Potassium ",
@"Praseodymium",
@"Promethium",
@"Protactinium",
@"Radium",
@"Radon",
@"Rhenium",
@"Rhodium",
@"Roentgenium",
@"Rubidium",
@"Ruthenium",
@"Rutherfordium",
@"Samarium",
@"Scandium",
@"Seaborgium",
@"Selenium",
@"Silicon",
@"Silver",
@"Sodium",
@"Strontium",
@"Sulfur",
@"Tantalum",
@"Technetium",
@"Tellurium",
@"Terbium",
@"Thallium",
@"Thorium",
@"Thulium",
@"Tin",
@"Titanium",
@"Tungsten",
@"Ununbium",
@"Ununhexium",
@"Ununoctium",
@"Ununpentium",
@"Ununquadium",
@"Ununseptium",
@"Ununtrium",
@"Uranium",
@"Vanadium",
@"Xenon",
@"Ytterbium",
@"Yttrium",
@"Zinc",
@"Zirconium", nil];
NSDictionary *ElementsDict = [NSDictionary dictionaryWithObject:ElementsArray forKey:@"Elements"];
[listOfItems addObject:ElementsDict];
//Initialize the copy array.
copyListOfItems = [[NSMutableArray alloc] init];
//Set the title
self.navigationItem.title = @"Elements";
//Add the search bar
self.tableView.tableHeaderView = searchBar;
searchBar.autocorrectionType = UITextAutocorrectionTypeNo;
searching = NO;
letUserSelectRow = YES;
}
-(IBAction) back:(id)sender{
[self.navigationController popViewControllerAnimated:NO];
}
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
#pragma mark -
#pragma mark Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
if (searching)
return 1;
else
return [listOfItems count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (searching)
return [copyListOfItems count];
else {
//Number of rows it should expect should be based on the section
NSDictionary *dictionary = [listOfItems objectAtIndex:section];
NSArray *array = [dictionary objectForKey:@"Elements"];
return [array count];
}
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
if(searching)
return @"Search Results";
if(section == 0)
return @"Elements";
}
// Customize the appearance of table view cells.
- (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];
}
// Configure the cell...
if(searching)
cell.text = [copyListOfItems objectAtIndex:indexPath.row];
else {
//First get the dictionary object
NSDictionary *dictionary = [listOfItems objectAtIndex:indexPath.section];
NSArray *array = [dictionary objectForKey:@"Elements"];
NSString *cellValue = [array objectAtIndex:indexPath.row];
cell.text = cellValue;
}
return cell;
}
- (NSIndexPath *)tableView :(UITableView *)theTableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if(letUserSelectRow)
return indexPath;
else
return nil;
}
- (void) searchBarTextDidBeginEditing:(UISearchBar *)theSearchBar {
//This method is called again when the user clicks back from teh detail view.
//So the overlay is displayed on the results, which is something we do not want to happen.
if(searching)
return;
//Add the overlay view.
if(ovController == nil)
ovController = [[OverlayViewController alloc] initWithNibName:@"OverlayView" bundle:[NSBundle mainBundle]];
CGFloat yaxis = self.navigationController.navigationBar.frame.size.height;
CGFloat width = self.view.frame.size.width;
CGFloat height = self.view.frame.size.height;
//Parameters x = origion on x-axis, y = origon on y-axis.
CGRect frame = CGRectMake(0, yaxis, width, height);
ovController.view.frame = frame;
ovController.view.backgroundColor = [UIColor grayColor];
ovController.view.alpha = 0.5;
ovController.rvController = self;
[self.tableView insertSubview:ovController.view aboveSubview:self.parentViewController.view];
searching = YES;
letUserSelectRow = NO;
self.tableView.scrollEnabled = NO;
//Add the done button.
self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemDone
target:self action:@selector(doneSearching_Clicked:)] autorelease];
}
- (void)searchBar:(UISearchBar *)theSearchBar textDidChange:(NSString *)searchText {
//Remove all objects first.
[copyListOfItems removeAllObjects];
if([searchText length] > 0) {
[ovController.view removeFromSuperview];
searching = YES;
letUserSelectRow = YES;
self.tableView.scrollEnabled = YES;
[self searchTableView];
}
else {
[self.tableView insertSubview:ovController.view aboveSubview:self.parentViewController.view];
searching = NO;
letUserSelectRow = NO;
self.tableView.scrollEnabled = NO;
}
[self.tableView reloadData];
}
- (void) searchBarSearchButtonClicked:(UISearchBar *)theSearchBar {
[self searchTableView];
}
- (void) searchTableView {
NSString *searchText = searchBar.text;
NSMutableArray *searchArray = [[NSMutableArray alloc] init];
for (NSDictionary *dictionary in listOfItems)
{
NSArray *array = [dictionary objectForKey:@"Elements"];
[searchArray addObjectsFromArray:array];
}
for (NSString *sTemp in searchArray)
{
NSRange titleResultsRange = [sTemp rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (titleResultsRange.length > 0)
[copyListOfItems addObject:sTemp];
}
[searchArray release];
searchArray = nil;
}
- (void) doneSearching_Clicked:(id)sender {
searchBar.text = @"";
[searchBar resignFirstResponder];
letUserSelectRow = YES;
searching = NO;
self.navigationItem.rightBarButtonItem = nil;
self.tableView.scrollEnabled = YES;
[ovController.view removeFromSuperview];
[ovController release];
ovController = nil;
[self.tableView reloadData];
}
// Override to support editing the table view. - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
} */
#pragma mark -
#pragma mark Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *selectedCountry = nil;
if(searching)
selectedCountry = [copyListOfItems objectAtIndex:indexPath.row];
else {
NSDictionary *dictionary = [listOfItems objectAtIndex:indexPath.section];
NSArray *array = [dictionary objectForKey:@"Countries"];
selectedCountry = [array objectAtIndex:indexPath.row];
}
//Initialize the detail view controller and display it.
if ([[listOfItems objectAtIndex:indexPath.row] isEqual:@"neon"]){
Neon *abo = [[Neon alloc] initWithNibName:@"Neon" bundle:nil];
//dvController.selectedCountry = selectedCountry;
[self.navigationController pushViewController:abo animated:YES];
[abo release];
}
}
#pragma mark -
#pragma mark Memory management
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Relinquish ownership any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Relinquish ownership of anything that can be recreated in viewDidLoad or on demand.
// For example: self.myOutlet = nil;
}
- (void)dealloc {
[back release];
[tableView release];
[super dealloc];
}
@end
According to the exception you are getting you are calling objectAtIndex:
with a value of 60 and the NSMutableArray
doesn't have anything in it (range 0..0). You need to fix this before you'll get to the push code.
You should be able to tell from the call stack in the debugger which array is being accessed when the exception occurs or you can add NSLog before you do objectAtIndex: to see what you have. For example, you have:
if ([[listOfItems objectAtIndex:indexPath.row] isEqual:@"neon"]){
If you add this next line before the one above, you would be able to see what index you are trying to access (indexPath.row) and how many you actually have in listOfItems:
NSLog(@"listOfItems has %d, accessing %d", [listOfItems count], indexPath.row);
Not knowing much about your code, I can't tell you the exact problem, however:
At the top, you differentiate between two different arrays depending on the value of searching
. Later, you only use the array you'd use when searching
is false, with the same index, which seems to be an array of NSDictionary
s, not NSString
s. You also seem to be accessing it using indexPath.section
the first time, and indexPath.row
the second time.
The line I'm talking about, in particular, is this one:
if ([[listOfItems objectAtIndex:indexPath.row] isEqual:@"neon"]){
Based on the previous code, that is, this line:
NSDictionary *dictionary = [listOfItems objectAtIndex:indexPath.section];
I'm guessing that listOfItems
contains a number of items equal to the number of sections in your table view, not the number of rows in the section you clicked in, and I'm also guessing that the return value will never be equal to @"neon"
because it is an NSDictionary
.
Solved with this code for anyone wondering. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { NSString *selectedCountry = nil;
if(searching)
selectedCountry = [copyListOfItems objectAtIndex:indexPath.row];
else {
NSDictionary *dictionary = [listOfItems objectAtIndex:indexPath.section];
NSArray *array = [dictionary objectForKey:@"Elements"];
selectedCountry = [array objectAtIndex:indexPath.row];
}
//Initialize the detail view controller and display it.
NSLog(@"listOfItems has %d, accessing %d", [listOfItems count], indexPath.row);
NSDictionary *dictionary = [listOfItems objectAtIndex:indexPath.section];
NSArray *array = [dictionary objectForKey:@"Elements"];
NSString *cellValue = [array objectAtIndex:indexPath.row];
if ([cellValue isEqual:@"neon"]){
NSLog(@"Neon");
Neon *abo = [[Neon alloc] initWithNibName:@"Neon" bundle:nil];
[self.navigationController pushViewController:abo animated:YES];
NSLog(@"Neon Worked");
[abo release];
}
}
精彩评论