2010-05-09 4 views
1

검색 막대를 구현하기위한 자습서를 따라 왔습니다.테이블에서 다른 뷰 밀어 내기

그러나 나는 다른 견해를 강요하는 것처럼 보이지 않습니다. 다음은 내 didsSelectRowAtIndexPath의 모양입니다. 이유 * 종료 응용 프로그램으로 인해 캐치되지 않는 예외에 'NSRangeException' 2010-05-09 08 : 47 : 27.516 iTeachU [307 3821] 나는 네온를 클릭하면 여기

- (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]; } } 

그리고

은 debuger 메시지입니다 : '*
- [NSMutableArray objectAtIndex :] : 인덱스 60 초과 [0 .. 0]' *** 처음 throw시 호출 스택 : 'NSException'인스턴스를 throw 한 후 호출 종료 프로그램 수신 신호 : "SIGABRT" .

누군가 셀 텍스트를 기반으로보기를 푸시 할 수있는 방법이 있다면 크게 감사하겠습니다. 감사합니다

편집 전체하는 .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]; 
} 

// 테이블 뷰 편집을 지원하기 위해 재정의합니다. - (무효)있는 tableView는 (jQuery과 *)있는 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 

답변

0

예외에 따르면 objectAtIndex:의 값은 60이고, NSMutableArray에는 아무 것도 없습니다 (범위 0..0). 푸시 코드를 사용하기 전에이 문제를 해결해야합니다.

예외가 발생할 때 어떤 배열에 액세스하고 있는지 디버거의 호출 스택에서 알 수 있어야합니다. 또는 objectAtIndex를 수행하기 전에 NSLog를 추가하여 소유하고있는 것을 확인할 수 있어야합니다.예를 들어, 당신은 : 위의 하나 전에이 다음 라인을 추가하면

if ([[listOfItems objectAtIndex:indexPath.row] isEqual:@"neon"]){ 

, 당신은 LISTOFITEMS에 액세스 (indexPath.row) 얼마나 많은에 어떤 인덱스 당신이하려고하는 당신이 실제로 가지고 볼 수있을 것입니다 :

NSLog(@"listOfItems has %d, accessing %d", [listOfItems count], indexPath.row); 
+0

답변 해 주셔서 감사합니다. 나는 세 번째 항목을 클릭하고 이것을 얻었다 : 2010-05-09 19 : 43 : 49.392 iTeachU [4674 : 307] listOfItems는 1을 가지고 있으며, 3을 액세스한다 행 3을 사용하여 뷰를 푸시하도록하는 방법이 있는가? 그? – Tanner

+0

잘못된 질문을하고 있습니다. 왜 listOfItems에 단 하나의 항목 만 있는지 묻는 것이 좋을까요? 거기에 1 개 밖에 없으면 어떻게 아이템 3을 꺼내기를 기대할 수 있습니까? – progrmr

0

은 코드에 대해 잘 몰라서 그러나 정확한 문제를 말할 수는 없습니다.

맨 위에는 searching의 값에 따라 두 개의 다른 배열을 구별합니다. 나중에 searching이 거짓 일 때 사용할 배열 만 사용합니다. 동일한 색인은 NSDictionary의 배열로 보이며 NSString이 아니라고 가정합니다. 처음으로 indexPath.section을 사용하고 두 번째로 indexPath.row을 사용하여 액세스하는 것 같습니다.

내가 말하는거야 라인은 특히이 하나입니다 : 앞의 코드를 기반으로

if ([[listOfItems objectAtIndex:indexPath.row] isEqual:@"neon"]){ 

, 즉,이 라인 :

NSDictionary *dictionary = [listOfItems objectAtIndex:indexPath.section]; 

내가 같은데요 listOfItems에는 클릭 한 섹션의 행 수가 아닌 테이블보기의 섹션 수와 동일한 항목이 많이 포함되어 있으며 NSDictionary이기 때문에 반환 값이 결코 @"neon"과 같지 않을 것이라고 추측합니다. .

+0

필자는 편집으로 클래스의 나머지 부분을 추가했다. 나는 여전히 밀어 붙일 견해를 얻을 수 없다. 제공된 코드를 사용하면 새로운보기를 얻을 수있는 것을 볼 수 있습니까? – Tanner

+0

유일한 항목이 "Elements"키를 사용하는 경우 어디에서이 "국가"배열이 왔을 것으로 기대합니까? –

+0

요소로 변경되었습니다. 선택이나 밀기에 변화가 없었습니다. – Tanner

0

궁금한 분은이 코드를 사용하여 해결하십시오. - (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]; 
} 

}

+0

그 중 하나가 문제를 해결했거나 올바른 방향으로 인도하는 데 도움이된다면 도움이된다면 하나 또는 upvote를 선택하는 것이 좋습니다. – progrmr

+0

문제는 그 하나의 견해를 푸는 의미에서 해결되었습니다. 그러나 검색 창은보기 사본을 사용합니다. 하나의 뷰만 푸시하도록 copyListItems 및 listItems를 가져올 수 있습니다. 다른 사용자를 선택하면 앱이 강제로 중단됩니다. 나는 여전히 모든 견해를 밀어 붙일 방법이 필요하다. – Tanner

+0

문자열을 선언하고 isEqual을 설정하면 모든 검색을 포함하여 작동합니다. nslog 코드가 도움이되었습니다. 나를 올바른 길로 인도하기 때문에 나는 그것을 답으로 표시 할 것이다. 도와 줘서 고마워. – Tanner

관련 문제