Select All,Deselect All and select particular cell in custom table view - ios

I have created a drop-down using table cell,where i am showing my data. My data is get display in drop down.Now I want all the cell should be selected initially. Also I want to deselect all cell, and individual cell.
(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([tableView isEqual:expansionTableView]) {
forState:UIControlStateNormal];
if (indexPath.row == 0) {
if ([indexPath isEqual:self.selectIndex]) {
self.isOpen = NO;
[self didSelectCellRowFirstDo:NO nextDo:NO];
self.selectIndex = nil;
}else
{
if (!self.selectIndex) {
self.selectIndex = indexPath;
[self didSelectCellRowFirstDo:YES nextDo:NO];
}else
{
[self didSelectCellRowFirstDo:NO nextDo:YES];
}
}
}else
{
objectForKey:#"surveyName"];
NSMutableArray *list=[[NSMutableArray alloc]init];
NSMutableArray *idlist =[[NSMutableArray alloc]init];
for (int i=0; i<_arraySurveyName.count; i++) {
NSMutableDictionary *dict=[_arraySurveyName objectAtIndex:i];
NSString *surveyName=[dict valueForKey:#"SurveyName"];
NSString *surveyID =[dict valueForKey:#"SurveyId"];
[list addObject:surveyName];
[idlist addObject:surveyID];
}
NSString *item = [list objectAtIndex:indexPath.row-1];
NSNumber *item1= [idlist objectAtIndex:indexPath.row-1];
str = item1;
NSLog(#"%#",str);
[_btn_surveyName setTitle:item forState:UIControlStateNormal];
[expansionTableView setHidden:YES];
}
}
else if ([tableView isEqual:expansionTableViewQtn]){
NSString *selectedQuestion=[arrayOfQuestionDetail objectAtIndex:indexPath.section];
[expansionTableViewQtn setHidden:YES];
[_btn_showQuestn setTitle:selectedQuestion forState:UIControlStateNormal];
}
}
it's my code for "didSelect".How to do this.

You can use below methods to select and deselect the cells
- (void)selectRowAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated scrollPosition:(UITableViewScrollPosition)scrollPosition;
- (void)deselectRowAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated;
[tableView deselectRowAtIndexPath:indexPath animated:NO];//For deselecting
[tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];//For selecting

Related

Buggy swipe to delete display on one more row after each delete

I'm having a weird issue on UITableView delete action since iOS 11.
Here's the relevant TableView code :
#implementation ChatMessageListViewController(TableView)
#pragma mark - table view datasource/delegate
- (NSArray<UITableViewRowAction *> *) tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(nonnull NSIndexPath *)indexPath{
NSMutableArray *rowActions = [NSMutableArray array];
UITableViewRowAction *delete = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDestructive title:#"Delete" handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
[self deleteMessageAtIndexPath:indexPath];
}];
delete.backgroundColor = [UIColor redColor];
[rowActions addObject:delete];
return [rowActions copy];
}
- (void) deleteMessageAtIndexPath:(NSIndexPath *)indexPath {
NSString *threadID = [[self.messageArray objectAtIndex:indexPath.row] objectForKey:#"threadID"];
[self.tableView beginUpdates];
[self.messageArray removeObjectAtIndex:indexPath.row];
[self.tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
[self.tableView endUpdates];
#weakify(self);
[UIUtil showLoadingHudWithText:WELocalString(#"message_remove_thread_loading_text", #"Deleting...", #"删除中...")];
[[AsyncUtil sharedInstance] dispatch_background_network:^{
DBManager *db = [[DBManager alloc] init];
[db deletetableData:[NSString stringWithFormat:#"singleChat WHERE threadID = '%#' ",threadID] ];
[[MemChatThreadMessages sharedInstance] removeThread:threadID];
NSDictionary * result = [Network deleteChatThread:threadID forEmail:[WEUtil getEmail]];
[[AsyncUtil sharedInstance] dispatch_main:^{
[UIUtil hideLoadingHuds];
#strongify(self);
if(self == nil) return ;
if([result[#"result"] isEqualToString:#"success"]){
}else{
[UIUtil showErrorMessage:WELocalString(#"message_remove_thread_error", #"Cannot delete this thread", #"不能删除该会话!")];
}
[self.tableView reloadData];
}];
}];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [self.messageArray count];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
NSDictionary *messageInfo = [self.messageArray objectAtIndex:indexPath.row];
if ([(NSString *)[messageInfo objectForKey:#"isAnnouncement"] isEqualToString:#"1"]) {
return 80;
}else if ([[messageInfo objectForKey:#"chatTag"] isValidString]){
return 80;
}else if([self isSpecialMessage:messageInfo]){
return 80;
}else{
return 67;
}
}
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"message";
if(self.events == nil){
NSDictionary * d = [WEUtil getMyEventListCache];
self.events = [[NSMutableDictionary alloc] init];
for(NSDictionary * eventSummary in d[#"events"]){
NSString * eventID = eventSummary[#"eventid"];
[self.events setObject:eventSummary forKey:eventID];
}
}
UserMessageTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil){
cell = [[UserMessageTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
}
if(indexPath.row >= [self.messageArray count]){
TERMINATE_WITH_NIL_CELL;
}
NSDictionary *messageInfo = [self.messageArray objectAtIndex:indexPath.row];
if(![self isSpecialMessage:messageInfo]){
[cell configureCellWithMessageDict:messageInfo];
}else{
[cell configureCellWithNewMessageDict:messageInfo withEvents:self.events];
}
return cell;
}
#pragma mark - Navigation
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
NSDictionary *msgThreadDict = [self.messageArray objectAtIndex:indexPath.row];
if(![self isSpecialMessage:msgThreadDict]){
[self tableView:tableView didSelectNormalRowAtIndexPath:indexPath];
}else{
NSString * event = msgThreadDict[#"event"];
if([event isValidString]){
if([event isEqualToString:#"no_event_messages"]){
[UIUtil showErrorMessage:#"no event id"];
}else{
[BackendTracking trackingWithAction:#"open_special" withLabel:#"threads_list"];
SpecialTopicListViewController * special = [[SpecialTopicListViewController alloc] init];
special.tracking_src = #"tab";
[self.navigationController pushViewController:special animated:YES];
}
}
}
}
-(void) tableView:(UITableView *)tableView didSelectNormalRowAtIndexPath:(NSIndexPath *)indexPath{
NSDictionary *msgThreadDict = [self.messageArray objectAtIndex:indexPath.row];
NSString *threadID = [msgThreadDict objectForKey:#"threadID"];
NSString *jid = [msgThreadDict objectForKey:#"jid"];
[GATracking trackCategory:#"message" withAction:#"thread_list_item_click" withLabel:threadID];
[[MemChatThreadMessages sharedInstance] setCurrentThreadID:threadID];
PrivateMessageViewController * chatVC = [[PrivateMessageViewController alloc] init];
chatVC.threadID = threadID;
chatVC.targetJID = jid;
chatVC.targetName = [msgThreadDict objectForKey:#"name"];
chatVC.unreadMsgNumber = [[self.messageArray objectAtIndex:indexPath.row][#"unreadCnt"] integerValue];
if ([(NSString *)[msgThreadDict objectForKey:#"isGroup"] isEqualToString:#"1"]) {
chatVC.isGroup = YES;
}else{
chatVC.isGroup = NO;
}
chatVC.src = #"list";
WELogInfo(#"click message");
[self.navigationController pushViewController:chatVC animated:YES];
}
#end
With the update and the changes using those trailing swipe actions there is another View appended before each time I delete an entry (until it doesn't work anymore). I've tried disabling the full trail or implementing iOS 11 trailingSwipeActionsConfigurationForRowAtIndexPath but I can't resolve this issue so far.
Do you see something wrong in the code? The main controller code is in another file.
Try reloading after you delete, after this line
[self.tableView endUpdates];
I think you removed the data from messageArray but as you are not reloading just after that so table view count is still 2 and you are reloading inside the block which might be taking time.
And one more thing you already removing data from messageArray, and then removing from db, So if you fail to remove it from db you are showing its not removed but for user it will be removed, as its no longer in message array

Checkmark multiple rows by loading NSUserDefaults

I'm asking the user to select options in a UITableView and then saving the selection in NSUserDefaults. I'm making sure that if the user selects an option twice, it gets added only once..i.e no duplicates.
I'm loading the NSUserDefaults and then trying to show the rows as "checked"..so that the user remembers what he/she had selected when they had run the app earlier.
Now, I know that only the cellForRowAtIndexPath method can set a checkmark.
The below code only checkmarks the last object. But how do I get multiple checkmarks?
This is how far I've gotten.
- (void)viewDidLoad {
[super viewDidLoad];
appSettings = [NSUserDefaults standardUserDefaults];
self.title = #"Select News Categories";
_selectedCategoriesArray = [[NSMutableArray alloc] init];
[self initNewsCategories];
[self loadNewsSelectedCategories];
}
#pragma mark UITableViewDataSource methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [_newsCategoriesArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cellNewsCategory" forIndexPath:indexPath];
// Configure the cell...
cell.textLabel.text = [NSString stringWithFormat:#"%#",[_newsCategoriesArray objectAtIndex:indexPath.row]];
NSString * cellText = [[cell textLabel] text];
for (NSString * lbl in _selectedNewsCategories)
{
if ([cellText isEqualToString:lbl])
{
[cell setAccessoryType:UITableViewCellAccessoryCheckmark];
}
else
{
[cell setAccessoryType:UITableViewCellAccessoryNone];
}
}
return cell;
}
#pragma mark UITableViewDelegate methods
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
UITableViewCell * selectedCell = [tableView cellForRowAtIndexPath:indexPath];
NSString * selectedCategory = [[selectedCell textLabel] text];
if ([tableView cellForRowAtIndexPath:indexPath].accessoryType == UITableViewCellAccessoryNone)
{
[[tableView cellForRowAtIndexPath:indexPath] setAccessoryType:UITableViewCellAccessoryCheckmark];
NSLog(#"%#", selectedCategory);
[_selectedCategoriesArray addObject:selectedCategory];
NSLog(#"_selectedCategoriesArray:%#", _selectedCategoriesArray);
[appSettings setObject:_selectedCategoriesArray forKey:#"selectedNewsCategories"];
}
else if ([tableView cellForRowAtIndexPath:indexPath].accessoryType == UITableViewCellAccessoryCheckmark)
{
[[tableView cellForRowAtIndexPath:indexPath] setAccessoryType:UITableViewCellAccessoryNone];
NSLog(#"%#", selectedCategory);
[_selectedCategoriesArray removeObject:selectedCategory];
NSLog(#"_selectedCategoriesArray:%#", _selectedCategoriesArray);
[appSettings setObject:_selectedCategoriesArray forKey:#"selectedNewsCategories"];
}
else
{
[[tableView cellForRowAtIndexPath:indexPath] setAccessoryType:UITableViewCellAccessoryNone];
}
[appSettings synchronize];
}
#pragma mark Helper methods
-(void) initNewsCategories
{
_newsCategoriesArray = [NSArray arrayWithObjects:#"Arts",#"Business",#"Company",
#"Entertainment",#"Environment",#"Health",#"Lifestyle",
#"Media",#"Money",#"Most Read",#"Trending",#"World",nil];
}
-(void) loadNewsSelectedCategories
{
_selectedNewsCategories = [[NSMutableArray alloc] init];
_selectedNewsCategories = [appSettings objectForKey:#"selectedNewsCategories"];
}
You have a problem in this code:
for (NSString * lbl in _selectedNewsCategories)
{
if ([cellText isEqualToString:lbl])
{
[cell setAccessoryType:UITableViewCellAccessoryCheckmark];
}
else
{
[cell setAccessoryType:UITableViewCellAccessoryNone];
}
}
You first checkmark cell but then you continue search and unmark cell.
You need to use this:
for (NSString * lbl in _selectedNewsCategories)
{
if ([cellText isEqualToString:lbl])
{
[cell setAccessoryType:UITableViewCellAccessoryCheckmark];
break;
}
else
{
[cell setAccessoryType:UITableViewCellAccessoryNone];
}
}
Or this
if([_selectedNewsCategories indexOfObject: cellText] != NSNotFound)
{
[cell setAccessoryType:UITableViewCellAccessoryCheckmark];
}else
{
[cell setAccessoryType:UITableViewCellAccessoryNone];
}

How to pass value in select UITableViewCell Row

I have UITableViewCell, cell indexing category wise and expand cell click on header, and load data by JSON. I want to select cell and pass data another view controller. I try to many times but pass data only first cell. I clicked another cell so this condition pass data first cell. Can't send particular cell data. How it possible . please help.
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSError *error;
NSMutableDictionary *json = [NSJSONSerialization JSONObjectWithData:response options:NSJSONReadingMutableLeaves error:&error];
NSArray *statuses = [json objectForKey:#"status"];
names=[[NSMutableArray alloc]initWithArray:[statuses valueForKey:#"business_category_name"]];
business_details_array=[[NSMutableArray alloc]initWithArray:[statuses valueForKey:#"business_details"]];
for (int i=0; i<[names count]; i++) {
[arrayForBool addObject:[NSNumber numberWithBool:NO]];
}
[self.tabel_view reloadData];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return names.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if ([[arrayForBool objectAtIndex:section] boolValue]) {
return [[business_details_array objectAtIndex:section] count];
}
else
return 0;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 70;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIView *sectionHeaderView=[[UIView alloc]initWithFrame:CGRectMake(0, 0, tableView.frame.size.width,70)];
sectionHeaderView.backgroundColor=[UIColor grayColor];
sectionHeaderView.tag=section;
UIView *sectionsubHeaderView=[[UIView alloc]initWithFrame:CGRectMake(0, 0, tableView.frame.size.width,60)];
sectionsubHeaderView.backgroundColor=[UIColor blueColor];
UIImageView *arrow=[[UIImageView alloc]initWithFrame:CGRectMake(0, 0,60, 60)];
[arrow setImage:[UIImage imageNamed:#"arrow.png"]];
UILabel *Lbl=[[UILabel alloc]initWithFrame:CGRectMake(60, 0,tableView.frame.size.width-60, 60)];
Lbl.text=[names objectAtIndex:section];
Lbl.textColor=[UIColor whiteColor];
[sectionsubHeaderView addSubview:arrow];
[sectionsubHeaderView addSubview:Lbl];
[sectionHeaderView addSubview:sectionsubHeaderView];
UITapGestureRecognizer *headerTapped = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(sectionHeaderTapped:)];
[sectionHeaderView addGestureRecognizer:headerTapped];
return sectionHeaderView;
}
- (void)sectionHeaderTapped:(UITapGestureRecognizer *)gestureRecognizer
{
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:gestureRecognizer.view.tag];
if (indexPath.row == 0) {
BOOL collapsed = [[arrayForBool objectAtIndex:indexPath.section] boolValue];
for (int i=0; i<[names count]; i++) {
if (indexPath.section==i) {
[arrayForBool replaceObjectAtIndex:i withObject:[NSNumber numberWithBool:!collapsed]];
}
}
[self.tabel_view reloadSections:[NSIndexSet indexSetWithIndex:gestureRecognizer.view.tag] withRowAnimation:UITableViewRowAnimationAutomatic];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
MemberTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"ht"];
if (cell==nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"Cell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
NSString*title_str=[NSString stringWithFormat:#"%#",[[[business_details_array objectAtIndex:indexPath.section] valueForKey:#"name"] objectAtIndex:indexPath.row]];
cell.title.text= title_str;
[titles addObject:title_str];
NSLog(#"get %#",titles);
cell.email.text=[NSString stringWithFormat:#"%#",[[[business_details_array objectAtIndex:indexPath.section] valueForKey:#"email"] objectAtIndex:indexPath.row]];
//[emailary addObject:cell.email.text];
cell.address_lbl.text=[NSString stringWithFormat:#"%#",[[[business_details_array objectAtIndex:indexPath.section] valueForKey:#"address"] objectAtIndex:indexPath.row]];
//[adrsary addObject:cell.address_lbl.text];
cell.phone_lbl.text=[NSString stringWithFormat:#"%#",[[[business_details_array objectAtIndex:indexPath.section] valueForKey:#"phone"] objectAtIndex:indexPath.row]];
// [phoneary addObject:cell.phone_lbl.text];
cell.web_lbl.text=[NSString stringWithFormat:#"%#",[[[business_details_array objectAtIndex:indexPath.section] valueForKey:#"website"] objectAtIndex:indexPath.row]];
//[websiteary addObject:cell.web_lbl.text];
cell.sens_lbl.text=[NSString stringWithFormat:#"%#",[[[business_details_array objectAtIndex:indexPath.section] valueForKey:#"member_since"] objectAtIndex:indexPath.row]];
//[sensary addObject:cell.sens_lbl.text];
cell.des_lbl.text=[NSString stringWithFormat:#"%#",[[[business_details_array objectAtIndex:indexPath.section] valueForKey:#"des"] objectAtIndex:indexPath.row]];
//[desary addObject:cell.des_lbl.text];
NSData* imageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString: [NSString stringWithFormat:#"%#",[[[business_details_array objectAtIndex:indexPath.section] valueForKey:#"img_url"] objectAtIndex:indexPath.row]]]];
UIImage* image = [[UIImage alloc] initWithData:imageData];
cell.image_view.image =image;
//[images addObject:cell.image_view.image];
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[arrayForBool replaceObjectAtIndex:indexPath.section withObject:[NSNumber numberWithBool:NO]];
[self.tabel_view reloadSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationAutomatic];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"showRecipeDetail"])
{
NSIndexPath *indexPath = [self.tabel_view indexPathForSelectedRow];
member_details *destViewController = segue.destinationViewController;
destViewController.hello = [titles objectAtIndex:indexPath.row];
}
}
As you have directly joined segue from tableview, it's not proper way to do that. Instead of you have to joined segue by controller to controller. So before getting proper selected row index, your view controller push fast and you are always getting 0 index.
Instead of writing logic in prepareForSegue, you can do the same stuff in didSelect method of UITablView.
For that you have to find your destination view controller from storyboard. And set the data to required property.
EDIT
Remove your prepare segure logic and do this in didSelect
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[arrayForBool replaceObjectAtIndex:indexPath.section withObject:[NSNumber numberWithBool:NO]];
[self.tabel_view reloadSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationAutomatic];
UIStoryboard *storyboard =
[UIStoryboard storyboardWithName:#"MainStoryboard"
bundle:[NSBundle mainBundle]];
YourDestinationVC *vc =[[storyboard instantiateViewControllerWithIdentifier:#"YourDestinationVC"]; //#"YourDestinationVC" is storyboardID for your destination view controller
vc.hello = [titles objectAtIndex:indexPath.row];
[[self navigationController] pushViewController:vc animated:YES];
}
Here is screenshot :
You should create your segues between viewcontrollers.
Do not create segue from cell to viewcontrollers.
Then you should call
[self performSegueWithIdentifier:#"showRecipeDetail" sender:self];
after updating the table in didSelectRowAtIndexPath
Try this remove prepare for prepareForSegue and in didselectrowatindexpath add.
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[arrayForBool replaceObjectAtIndex:indexPath.section withObject:[NSNumber numberWithBool:NO]];
[self.tabel_view reloadSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationAutomatic];
member_details *destViewController = [[member_details alloc]init];
destViewController.hello = [titles objectAtIndex:indexPath.row];
[[self navigationController] pushViewController:destViewController animated:YES];
}
Try This
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self performSegueWithIdentifier:#"showRecipeDetail" sender:[YOUR_ARRAY objectAtIndex:indexPath.row]];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"showRecipeDetail"])
{
member_details *destViewController = segue.destinationViewController;
destViewController.hello = sender;
}
}

iOS Search Address book contacts by UISearchBar using NSDictionary with multiple arrays

I am trying to implement search bar in my custom Contacts Book. I created NSDictionary for search data and added to my dictionary 4 mutable arrays, include
names, last name, phone types, phone numbers.
When I am trying to search in NSDictionary, my app is crashing on cell create. And When I am searching by one array only (from dictionary valueforkey or directly from array) it's working partially, but taking another strings (for example last name) always from the first contact in the list. Bacause not all parameters in a loop, So I have to search by every parameter to get right first name and last name in my contacts.
here is my code:
#pragma mark SEARCH_BAR
-(void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
[self.tableSearchBar resignFirstResponder];
}
-(void)searchBar:(UISearchBar *)serachBar textDidChange:(NSString *)searchText {
[filteredStrings removeAllObjects];
if (searchText.length == 0) {
isFiltered = NO;
} else {
isFiltered = YES;
//here aim creating NSDictionary with 4 Mutable Arrays
NSDictionary *filteredContacts = [NSDictionary dictionaryWithObjectsAndKeys:
contacts.firstNames, #"First Name",
contacts.lastNames, #"Last Name",
contacts.phoneTypes, #"Phone Type",
contacts.phoneNumbers, #"Phone Numbers",
nil];
//[filteredStrings addObject:filteredContacts];
for (NSString *str in filteredContacts) { // in this case for (NSString *str in [filteredContacts valueForKey:#"First Name"]) all working partially
NSRange stringRange = [str rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (stringRange.location != NSNotFound) {
filteredStrings = [[NSMutableArray alloc]init];
[filteredStrings addObject:str];
}
}
}
[self.contactsTableView reloadData];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (isFiltered) {
return [filteredStrings count];
}
return [contacts.firstNames count];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellID = #"Cell";
abCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
if (!cell) {
cell = [tableView dequeueReusableCellWithIdentifier:cellID];
}
if (!isFiltered) {
cell.firstNameLabel.text = [contacts.firstNames objectAtIndex:indexPath.row];
cell.lastNameLabel.text = [contacts.lastNames objectAtIndex:indexPath.row];
cell.contactImage.image = [UIImage imageNamed:#"NOIMG.png"];
} else {
cell.firstNameLabel.text = [filteredStrings objectAtIndex:indexPath.row]; // Here my app is crashing when trying to search by all nsdictionary.
cell.lastNameLabel.text = [filteredStrings objectAtIndex:indexPath.row];
//cell.contactImage.image = [UIImage imageNamed:#"NOIMG.png"];
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[self.contactsTableView deselectRowAtIndexPath:indexPath animated:YES];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"NextView"]) {
//if (!isFiltered) {
ContactDetailsViewController *nextController = [segue destinationViewController];
NSIndexPath *indexPath = [[[self contactsTableView] indexPathsForSelectedRows] objectAtIndex:0];
[nextController setPhoneTypes:[contacts.phoneTypes objectAtIndex:[indexPath row]]];
[nextController setPhoneNumbers:[contacts.phoneNumbers objectAtIndex:[indexPath row]]];
//}
/*else {
ContactDetailsViewController *nextController = [segue destinationViewController];
NSIndexPath *indexPath = [[[self contactsTableView] indexPathsForSelectedRows] objectAtIndex:0];
[nextController setPhoneTypes:[contacts.phoneTypes objectAtIndex:[indexPath row]]];
[nextController setPhoneNumbers:[contacts.phoneNumbers objectAtIndex:[indexPath row]]];
}*/
}
}

UISearchBar misses elements in the non-visible part of the tableView

I have a TableView with many rows, most are not visible at the time of loading viewController. The rows of UITableView are extracted from a SQLite database. How can I make do that the SearchBar search between all rows and not just the visible ones?
In header file:
#interface ExhibitorsViewController : UIViewController <UITableViewDataSource, UITableViewDelegate, UISearchBarDelegate>{
BOOL isSearchOn;
BOOL canSelectRow;
NSMutableArray * listOfExpositors;
NSMutableArray * searchResult;
}
//....
#end
In implementation file
-(NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section
{
if(isSearchOn){
return [searchResult count];
//In this array there are the elements after use of searchBar
}else{
int number=[self.mutableArray count];
//In this array there are all elements of database, extracts in viewDidLoad()
return number;
}
}
- (UITableViewCell *)tableView:(UITableView *)aTableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier] ;
}
if(isSearchOn){
NSString * cellValue = [searchResult objectAtIndex:indexPath.row];
cell.textLabel.text = cellValue;
}else{
//loading data from the database
Database *currow =[self.mutableArray objectAtIndex:indexPath.row];
cell.textLabel.text = currow.name;
[listOfExpositors addObject:cell.textLabel.text];
//here only loads the list of names visible and not the entire table
//How do I put all the elements in this array?
NSLog(#" %#", listOfExpositors);
isSearchOn = NO;
canSelectRow = YES;
}
}
-(void) doneSearching{
isSearchOn = NO;
canSelectRow = YES;
self.tableView.scrollEnabled = YES;
[self.searchBar resignFirstResponder];
[self.tableView reloadData];
}
-(void) searchBarTextDidBeginEditing:(UISearchBar *)searchBar{
isSearchOn = YES;
if(self.searchBar.text.length>0){
canSelectRow=YES;
self.tableView.scrollEnabled = YES;
}else{
canSelectRow= NO;
self.tableView.scrollEnabled = NO;
}
}
-(void) searchExpositorsTableView{
[searchResult removeAllObjects];
for (NSString *str in listOfExpositors){
NSRange titleResultsRange = [str rangeOfString:self.searchBar.text options:
NSCaseInsensitiveSearch];;
if (titleResultsRange.length >0) {
[searchResult addObject:str];
}
}
NSLog(#"%#", searchResult);
}
-(void) searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText{
if([searchText length]>0){
canSelectRow = YES;
self.tableView.scrollEnabled = YES;
[self searchExpositorsTableView];
}else{
canSelectRow = NO;
self.tableView.scrollEnabled = NO;
}
[self.tableView reloadData];
}
-(void) searchBarSearchButtonClicked:(UISearchBar *)searchBar{
[self searchExpositorsTableView];
[self.searchBar resignFirstResponder];
}
-(NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath{
if(canSelectRow){
return indexPath;
}else{
return nil;
}
NSLog(#"%d", indexPath.row);
}
It was wrong to use the array created in cellForRowAtIndexPath because it was limited only to the visible elements. I then used the NSMutableArray created in viewDidLoad () that does contain all the elements of the database. I changed the following methods:
- (UITableViewCell *)tableView:(UITableView *)aTableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//....
if(isSearchOn){
NSString * cellValue = [searchResult objectAtIndex:indexPath.row];
cell.textLabel.text = cellValue;
}else{
Database *currow =[self.mutableArray objectAtIndex:indexPath.row];
cell.textLabel.text = currow.name;
//Should be removed this array and used to another, self.mutableArray
//[listOfExpositors addObject:cell.textLabel.text];
// NSLog(#" %#", listOfExpositors);
isSearchOn = NO;
canSelectRow = YES;
}
}
Method for research
-(void) searchExpositorsTableView{
[searchResult removeAllObjects];
for (Database *currow in self.mutableArray){
/*In self.mutableArray there are all elements because is created in
viewDidLoad*/
NSLog(#"list of expositors %#", self.mutableArray);
NSRange titleResultsRange = [currow.name rangeOfString:self.searchBar.text options: NSCaseInsensitiveSearch];
if (titleResultsRange.length >0) {
[searchResult addObject:currow.name];
}
}
NSLog(#"%#", searchResult);
}

Resources