UISearchBar with scope buttons NSInternalInconsistencyException Crash on Cancel - iphone

I'm at sort of a loss here.
I have a UISearchBar with two scope buttons Option A and Option B. Searching works just fine on both scope buttons but when I click Cancel out of the search bar with the second scope button selected the app will sometimes crash with this error:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'no object at index 3 in section at index 0'
Here's the relevant code for my UITableView:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
NSArray *results = [fetchedResultsController fetchedObjects];
return [[fetchedResultsController sections] count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
id <NSFetchedResultsSectionInfo> sectionInfo = [[fetchedResultsController sections] objectAtIndex:section];
return [sectionInfo numberOfObjects];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
if (tableView == self.tableView && [[fetchedResultsController sections] count] > section) {
id <NSFetchedResultsSectionInfo> sectionInfo = [[fetchedResultsController sections] objectAtIndex:section];
return [sectionInfo name];
}
return nil;
}
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
NSArray *alphabet = [NSArray arrayWithObjects:UITableViewIndexSearch, #"A", #"B", #"C",#"D",#"E",#"F",#"G",#"H",#"I",#"J",#"K",#"L",#"M",#"N",#"O",#"P",#"Q",#"R",#"S",#"T",#"U",#"V",#"W",#"X",#"Y",#"Z",#"#",nil];
if (tableView == self.tableView) {
return alphabet;
}
return nil;
}
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
if(tableView == self.tableView && [title isEqual:UITableViewIndexSearch]){
[tableView scrollRectToVisible:[[tableView tableHeaderView] bounds] animated:NO];
return -1;
} else if (tableView == self.tableView) {
return [self.fetchedResultsController.sectionIndexTitles indexOfObject:title];
}
return 0;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"OptionACell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
NSManagedObject *category = [fetchedResultsController objectAtIndexPath:indexPath];
if (self.searchBar.selectedScopeButtonIndex == CategoriesViewSearchScopeOptionB && ![self.searchBar.text isEqual:#""]) {
[cell.textLabel setText:[category valueForKey:#"text"]];
} else {
[cell.textLabel setText:[category valueForKey:#"name"]];
}
return cell;
}
And the UISearchBar:
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
if([self.searchBar.text isEqual: #""] && self.searchBar.selectedScopeButtonIndex == CategoriesViewSearchScopeOptionB) {
self.searchBar.text=#"";
[self updateOptionAFetchRequest];
} else {
[self updateFetchRequest];
NSFetchedResultsController *fetchController = [self fetchedResultsController];
}
}
- (void)searchBarCancelButtonClicked:(UISearchBar *) searchBar {
[self logSearchTerm:self.searchBar.text];
self.searchBar.text = #"";
self.searchBar.selectedScopeButtonIndex = CategoriesViewSearchScopeOptionA;
[self updateOptionAFetchRequest];
self.searchDisplayController.delegate = nil;
}
- (BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar {
[self logSearchTerm:self.searchBar.text];
if([self.searchBar.text isEqual: #""]) self.searchBar.selectedScopeButtonIndex = CategoriesViewSearchScopeOptionA;
return YES;
}
- (void)searchBar:(UISearchBar *)searchBar selectedScopeButtonIndexDidChange:(NSInteger)selectedScope {
if([self.searchBar.text length] > 0) {
[self updateFetchRequest];
}
}
- (void)updateFetchRequest {
if (self.searchBar.selectedScopeButtonIndex == CategoriesViewSearchScopeOptionB) {
[self updateOptionBFetchRequest];
return;
}
[self updateOptionAFetchRequest];
}
I'm having trouble discerning the exact pattern of the crashing. It seems to crash consistently whenever I perform the action of opening the UISearchBar, clicking OptionB then Canceling. But when I open the SearchBar, click back and forth between the scope buttons and perform a couple searches, I'm able to close no problem.
Any help from Core Data experts would be greatly appreciated.

Related

Search Results not visible

I have a table view with a search display controller. When I type a search the log shows me the search is working and filtering properly however the screen only shows "No Results". I'm using Core Data if that makes a difference.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
if (tableView == self.searchDisplayController.searchResultsTableView) {
return [searchResults count];
}
else{
return[[self.fetchedResultsController sections]count];
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
id <NSFetchedResultsSectionInfo> secInfo = [[self.fetchedResultsController sections]objectAtIndex:section];\
return [secInfo numberOfObjects];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell;
static NSString *CellIdentifier = #"Cell";
if (tableView != self.tableView) {
NSLog(#"Found searchDisplayController");
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
} else {
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
NSLog(#"Found regular table View");
}
// Configure the cell...
Instance *instance = [self.fetchedResultsController objectAtIndexPath:indexPath];
if (tableView == self.searchDisplayController.searchResultsTableView) {
cell.textLabel.text = [searchResults objectAtIndex:indexPath.row];
} else {
cell.textLabel.text = instance.name;
}
Here are NumberOfRowsInSection and Number:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
if (tableView == self.searchDisplayController.searchResultsTableView) {
return [searchResults count];
}
else{
return[[self.fetchedResultsController sections]count];
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
id <NSFetchedResultsSectionInfo> secInfo = [[self.fetchedResultsController sections]objectAtIndex:section];\
return [secInfo numberOfObjects];
}
Check your implementation of numberOfSectionsInTableView and numberOfRowsInSection.
In the first, you should return 1 if it's the search table view (1 section).
In numberOfRowsInSection you should also check the given tableView argument as you did in numberOfSectionsInTableView and return [searchResults count].
Shouldn't your implementation be something like :-
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
if (tableView == self.searchDisplayController.searchResultsTableView)
{
return 1;
}
else
{
return[[self.fetchedResultsController sections]count];
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if(tableView == self.searchDisplayController.searchResultsTableView)
{
return [searchResults count];
}
id <NSFetchedResultsSectionInfo> secInfo = [[self.fetchedResultsController sections]objectAtIndex:section];\
return [secInfo numberOfObjects];
}
If the number of search results is high, then I would suggest using another Fetched Results Controller instead of an array.

Plist Search of Tableview

I have Plist which is been populated on the tableview with expanded sections ..now i want to search the table..below in images you can see what is happening when I search anything.
.
just because I am searching it but need some changes in the cellforrowatindexpath for search results....
please check the code and let me know what to do for searching plist..
what should be changes for the cellforrowatindexpath and noofrowsinsection for search from plist
.
.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [self.mySections count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSInteger rows = 0;
if ([self tableView:tableView canCollapseSection:section] || !(tableView == self.searchDisplayController.searchResultsTableView) )
{
if ([expandedSections containsIndex:section] )
{
NSString *key = [self.mySections objectAtIndex:section];
NSArray *dataInSection = [[self.myData objectForKey:key] objectAtIndex:0];
return [dataInSection count];
}
return 1;
} else if(tableView == self.searchDisplayController.searchResultsTableView) {
rows = [self.searchResults count];
return rows;
}
return 1;
}
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection: (NSInteger)section {
NSString *key = [self.mySections objectAtIndex:section];
return [NSString stringWithFormat:#"%#", key];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
//some changes required to display plst
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] ;
}
// Configure the cell...
if ([tableView isEqual:self.searchDisplayController.searchResultsTableView]) {
cell.textLabel.text = [self.searchResults objectAtIndex:indexPath.row];
}else {
NSUInteger section = [indexPath section];
NSUInteger row = [indexPath row];
NSString *key = [self.mySections objectAtIndex:section];
NSDictionary *dataForSection = [[self.myData objectForKey:key] objectAtIndex:0];
NSArray *array=dataForSection.allKeys;
cell.textLabel.text = [[dataForSection allKeys] objectAtIndex:row];
cell.detailTextLabel.text=[dataForSection valueForKey:[array objectAtIndex:indexPath.row]];
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([self tableView:tableView canCollapseSection:indexPath.section])
{
if (!indexPath.row)
{
// only first row toggles exapand/collapse
[tableView deselectRowAtIndexPath:indexPath animated:YES];
NSInteger section = indexPath.section;
BOOL currentlyExpanded = [expandedSections containsIndex:section];
NSInteger rows;
NSMutableArray *tmpArray = [NSMutableArray array];
if (currentlyExpanded)
{
rows = [self tableView:tableView numberOfRowsInSection:section];
[expandedSections removeIndex:section];
}
else
{
[expandedSections addIndex:section];
rows = [self tableView:tableView numberOfRowsInSection:section];
}
for (int i=1; i<rows; i++)
{
NSIndexPath *tmpIndexPath = [NSIndexPath indexPathForRow:i
inSection:section];
[tmpArray addObject:tmpIndexPath];
}
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if (currentlyExpanded)
{
[tableView deleteRowsAtIndexPaths:tmpArray
withRowAnimation:UITableViewRowAnimationTop];
cell.accessoryView = [DTCustomColoredAccessory accessoryWithColor:[UIColor grayColor] type:DTCustomColoredAccessoryTypeDown];
}
else
{
[tableView insertRowsAtIndexPaths:tmpArray
withRowAnimation:UITableViewRowAnimationTop];
cell.accessoryView = [DTCustomColoredAccessory accessoryWithColor:[UIColor grayColor] type:DTCustomColoredAccessoryTypeUp];
}
}
}
}
- (void)filterContentForSearchText:(NSString*)searchText
scope:(NSString*)scope
{
NSPredicate *resultPredicate = [NSPredicate
predicateWithFormat:#"SELF contains[cd] %#",
searchText];
self.searchResults = [self.mySections filteredArrayUsingPredicate:resultPredicate];
}
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
UISearchBar * searchBar = [controller searchBar];
[self filterContentForSearchText:searchString scope:[[searchBar scopeButtonTitles] objectAtIndex:[searchBar selectedScopeButtonIndex]]];
return YES;
}
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption
{
UISearchBar * searchBar = [controller searchBar];
[self filterContentForSearchText:[searchBar text] scope:[[searchBar scopeButtonTitles] objectAtIndex:searchOption]];
return YES;
}
The search results you are using in numberOfRows should be used for numberOfSections
Since you are filtering for section title and not rows.

How to perform Validation in ios uitableview (group table)?

In my app i have used UItableview group table.
In which there are two section and i want to perform validation on it.
for eg:In section 1 there are two row's,if user select row one user have to select some value from section 2 and if user have select second row in 1 section then no need of selection in section two.
following is my code:
- (void)viewDidLoad
{
NSArray *arr_data1 =[[NSArray alloc]initWithObjects:#"Yes",#"No",nil];
NSArray *arr_data2 =[[NSArray alloc] initWithObjects:#"Monotherapy",#"Adjunctive",nil];
NSDictionary *temp =[[NSDictionary alloc]
initWithObjectsAndKeys:arr_data1,#"",arr_data2,
#"Was it monotherapy or adjunctive",nil];
self.tableContents =temp;
self.arr_data =[[self.tableContents allKeys]
sortedArrayUsingSelector:#selector(compare:)];
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [self.arr_data count];
}
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return [self.arr_data objectAtIndex:section];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSArray *listData =[self.tableContents objectForKey:
[self.arr_data objectAtIndex:section]];
return [listData count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *SimpleTableIdentifier = #"SimpleTableIdentifier";
NSArray *listData =[self.tableContents objectForKey:
[self.arr_data objectAtIndex:[indexPath section]]];
UITableViewCell * cell = [tableView
dequeueReusableCellWithIdentifier: SimpleTableIdentifier];
if(cell == nil) {
cell = [[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:SimpleTableIdentifier];
}
NSUInteger row = [indexPath row];
cell.textLabel.text = [listData objectAtIndex:row];
return cell;
}
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSArray *listData =[self.tableContents objectForKey:
[self.arr_data objectAtIndex:[indexPath section]]];
NSUInteger row = [indexPath row];
NSLog(#"fdfdfdf=%d",[indexPath row]);
NSString *rowValue = [listData objectAtIndex:row];
if ([rowValue isEqualToString:#"Yes"])
{
NSString *message = [[NSString alloc] initWithFormat:#"%#",rowValue];
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"You selected"
message:message delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
In - (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath ,
you can check the section you need by using the following code:
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.section == 0)
{
//do as per you requirement
}
else if(indexPath.section == 1)
{
//do as per you requirement
}
}
You can first declare a variable count to keep track of how many items are selected in section 2 and isItemRequired as a flag variable and sythesize them, then use these delegates:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
A sample code to begin with:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.section == 0)
{
if(indexPath.row == 0)
{
isItemRequired = YES;
if(isItemRequired && count==0)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Item Required" message:#"You must have to select one or more item in section 2" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil ];
[alert show];
}
}
else
{
isItemRequired = NO;
}
}
else if(indexPath.section == 1)
{
count = 0;
for (int i=0; i < [tableView numberOfRowsInSection:1]; i++)
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:1]];
if(cell.selected==YES)
{
count++;
}
}
}
}
-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.section == 1)
{
count = 0;
for (int i=0; i < [tableView numberOfRowsInSection:1]; i++)
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:1]];
if(cell.selected==YES)
{
count++;
}
}
if(isItemRequired && count==0)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Item Required" message:#"Atleast one item should be selected in section 2" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil ];
[alert show];
}
}
}
In the didselect method of UITableView, you needs to check the section number & then check which row is clicked from that section
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 0)
{
if (indexPath.row == 0)
{
//do this
}
else if (indexPath.row == 1)
{
//do this
}
}
else
{
//do this
}
}
In the following delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
add a check with the help of indexPath returned by the delegate, it will tell you that which section's which row is selected like :
if(indexPath.section == 0 && indexPath.row == 0)
{
// Select something from the another section also
}
else if(indexPath.section == 0 && indexPath.row == 1)
{
// No need to select from another section.
}
First Take one BOOL variable with isYes in .h file like bellow...
BOOL isYes;
after in viewDidLoad: method just assign it to NO like bellow..
isYes = NO;
after that in didSelectRowAtIndexPath delegate method just use like bellow...
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
if(indexPath.section == 0 && indexPath.row == 0)
{
isYes = YES;
}
else if(indexPath.section == 0 && indexPath.row == 1)
{
isYes = NO;
}
if(isYes){
if(indexPath.section == 1 )
{
//here user can select the section 2
}
}
}
i hope this help you....

UISearchView not displaying search values

In my TableView which Expands on the clicking on the sections.now I am using Uisearchbar to search the sections in the table...It gives me the UIsearchbar but Search cannot be taken...
I think problem is in the numberOfRowsInSection.please check where I am getting wrong..
why searchbar is not working
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [self.mySections count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSInteger rows = 0;
if ([self tableView:tableView canCollapseSection:section] || (tableView == self.searchDisplayController.searchResultsTableView) )
{
if ([expandedSections containsIndex:section] )
{
NSString *key = [self.mySections objectAtIndex:section];
NSArray *dataInSection = [[self.myData objectForKey:key] objectAtIndex:0];
return [dataInSection count];
}
return 1;
} else{
rows = [self.searchResults count];
return rows;
}
return 1;
}
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection: (NSInteger)section {
NSString *key = [self.mySections objectAtIndex:section];
return [NSString stringWithFormat:#"%#", key];
}
- (void)filterContentForSearchText:(NSString*)searchText
scope:(NSString*)scope
{
NSPredicate *resultPredicate = [NSPredicate
predicateWithFormat:#"SELF contains[cd] %#",
searchText];
self.searchResults = [self.allItems filteredArrayUsingPredicate:resultPredicate];
}
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
UISearchBar * searchBar = [controller searchBar];
[self filterContentForSearchText:searchString scope:[[searchBar scopeButtonTitles] objectAtIndex:[searchBar selectedScopeButtonIndex]]];
return YES;
}
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption
{
UISearchBar * searchBar = [controller searchBar];
[self filterContentForSearchText:[searchBar text] scope:[[searchBar scopeButtonTitles] objectAtIndex:searchOption]];
return YES;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] ;
}
// Configure the cell...
if ([tableView isEqual:self.searchDisplayController.searchResultsTableView]) {
cell.textLabel.text = [self.searchResults objectAtIndex:indexPath.row];
}else {
NSUInteger section = [indexPath section];
NSUInteger row = [indexPath row];
NSString *key = [self.mySections objectAtIndex:section];
NSDictionary *dataForSection = [[self.myData objectForKey:key] objectAtIndex:0];
NSArray *array=dataForSection.allKeys;
cell.textLabel.text = [[dataForSection allKeys] objectAtIndex:row];
cell.detailTextLabel.text=[dataForSection valueForKey:[array objectAtIndex:indexPath.row]];
}
return cell;
}
You are not reloading your table after searching
- (void)filterContentForSearchText:(NSString*)searchText
scope:(NSString*)scope
{
NSPredicate *resultPredicate = [NSPredicate
predicateWithFormat:#"SELF contains[cd] %#",
searchText];
self.mySections = [self.mySections filteredArrayUsingPredicate:resultPredicate];
[myTableView reloadData];
}
Edit
Your are not setting detail text label
if ([tableView isEqual:self.searchDisplayController.searchResultsTableView])
{
cell.textLabel.text = [self.searchResults objectAtIndex:indexPath.row];
cell.detailTextLabel.text=[dataForSection valueForKey:[self.searchResults objectAtIndex:indexPath.row]];
}
and after searching you are getting title now row because in your code
rows = [self.searchResults count];
return rows;
its always returning zero value. So just do it return 1;
And do other thing as your requirement,
And i will suggest you to not to use different different code for before table search and after searching.. Like if ([tableView isEqual:self.searchDisplayController.searchResultsTableView])
just use same code for both..and make changes only in array and dictionary..
initially
tableAry = globalAry;
And after searching
tableAry = searchedAry;

How to implement Alphabetical section headers in a UITableView having content getting from DataBase

Till now I have implemented UITableView by populate the contents from the database
By retrieving in an array from sqlite data base
storedContactsArray = [Sqlitefile selectAllContactsFromDB];
so no multiple sections , section headers and returns storedContactsArray.count as number of rows.
Now i need to populate the same data in table view but The data set in Alpabetical sections in alphabetical order.
I tried with
alphabetsArray =[[NSMutableArray alloc]initWithObjects:#"A",#"B",#"C",#"D",#"E",#"F",#"G",#"H",#"I",#"J",#"K",#"L",#"M",#"N",#"O",#"P",#"Q",#"R",#"S",#"T",#"U",#"V",#"W",#"X",#"Y",#"Z",nil];
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [alphabetsArray count];
}
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
return alphabetsArray;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return [alphabetsArray objectAtIndex:section];
}
But in case of numberOfRowsInSection it fails since there is no contacts in storedContactsArray initially
Error occurs: -[__NSArrayM objectAtIndex:]: index 25 beyond bounds for empty array
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [[storedContactsArray objectAtIndex:section] count]
}
any advice of use full links pls
To achieve your requirement you need to first separate out all the data in to section as Alphabetical order. which is as following.
Here section is a Mutable Dictionary in which we will get all data as alphabetical sets.
//Inside ViewDidLoad Method
sections = [[NSMutableDictionary alloc] init]; ///Global Object
BOOL found;
for (NSString *temp in arrayYourData)
{
NSString *c = [temp substringToIndex:1];
found = NO;
for (NSString *str in [sections allKeys])
{
if ([str isEqualToString:c])
{
found = YES;
}
}
if (!found)
{
[sections setValue:[[NSMutableArray alloc] init] forKey:c];
}
}
for (NSString *temp in arrayYourData)
{
[[sections objectForKey:[temp substringToIndex:1]] addObject:temp];
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [[sections allKeys]count];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [[sections valueForKey:[[[sections allKeys] sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)] objectAtIndex:section]] 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];
}
NSString *titleText = [[sections valueForKey:[[[sections allKeys] sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)] objectAtIndex:indexPath.section]] objectAtIndex:indexPath.row];
cell.textLabel.text = titleText;
return cell;
}
Please try it I am using it and it working fine
Hope it helps you !!!