I am searching the table view data. Tableview contains contact list and when I give the contact name it's not able to give search bar result. Here is my code:
- (void)viewDidLoad
{
[super viewDidLoad];
// Hide the search bar until user scrolls up
CGRect newBounds = [[self tableview] bounds];
newBounds.origin.y = newBounds.origin.y + search.bounds.size.height;
[[self tableview] setBounds:newBounds];
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(goToSearch)];
self.navigationItem.rightBarButtonItem=doneButton;
self.filtereditems=[NSMutableArray arrayWithCapacity:[array count]];
[self loadPhoneContacts];
[[self tableview] reloadData];
}
- (void)goToSearch
{
[search becomeFirstResponder];
}
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller
shouldReloadTableForSearchString:(NSString *)searchString
{
// Tells the table data source to reload when text changes
[self filterContentForSearchText:searchString scope:
[[self.searchDisplayController.searchBar scopeButtonTitles] objectAtIndex:
[self.searchDisplayController.searchBar selectedScopeButtonIndex]]];
// Return YES to cause the search result table view to be reloaded.
return YES;
}
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller
shouldReloadTableForSearchScope:(NSInteger)searchOption
{
// Tells the table data source to reload when scope bar selection changes
[self filterContentForSearchText:[self.searchDisplayController.searchBar text] scope:
[[self.searchDisplayController.searchBar scopeButtonTitles] objectAtIndex:searchOption]];
// Return YES to cause the search result table view to be reloaded.
return YES;
}
-(void)loadPhoneContacts{
ABAuthorizationStatus status = ABAddressBookGetAuthorizationStatus();
if (status == kABAuthorizationStatusDenied) {
[[[UIAlertView alloc] initWithTitle:nil message:#"This app requires access to your contacts to function properly. Please visit to the \"Privacy\" section in the iPhone
Settings app." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil] show];
return;
}
CFErrorRef error = NULL;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error);
if (error) {
NSLog(#"ABAddressBookCreateWithOptions error: %#", CFBridgingRelease(error));
if (addressBook) CFRelease(addressBook);
return;
}
if (status == kABAuthorizationStatusNotDetermined)
{
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
if (error) {
NSLog(#"ABAddressBookRequestAccessWithCompletion error: %#",
CFBridgingRelease(error));
}
if (granted) {
// if they gave you permission, then just carry on
[self listPeopleInAddressBook:addressBook];
} else {
dispatch_async(dispatch_get_main_queue(), ^{
[[[UIAlertView alloc] initWithTitle:nil message:#"This app requires access to
your contacts to function properly. Please visit to the \"Privacy\" section in the iPhone
Settings app." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil] show];
});
}
if (addressBook) CFRelease(addressBook);
});
} else if (status == kABAuthorizationStatusAuthorized) {
[self listPeopleInAddressBook:addressBook];
if (addressBook) CFRelease(addressBook);
}
}
- (void)listPeopleInAddressBook:(ABAddressBookRef)addressBook
{
NSInteger numberOfPeople = ABAddressBookGetPersonCount(addressBook);
NSMutableArray * contactList=
CFBridgingRelease(ABAddressBookCopyArrayOfAllPeople(addressBook));
array =[[NSMutableArray alloc] init];
for (int i = 0; i < numberOfPeople; i++)
{
ABRecordRef person = (__bridge ABRecordRef)contactList[i];
firstName = CFBridgingRelease(ABRecordCopyValue(person, kABPersonFirstNameProperty));
lastName = CFBridgingRelease(ABRecordCopyValue(person, kABPersonLastNameProperty));
NSLog(#"Name:%# %#", firstName, lastName);
ABMultiValueRef phoneNumbers = ABRecordCopyValue(person, kABPersonPhoneProperty);
CFIndex numberOfPhoneNumbers = ABMultiValueGetCount(phoneNumbers);
for (CFIndex i = 0; i < numberOfPhoneNumbers; i++)
{
phoneNumber = CFBridgingRelease(ABMultiValueCopyValueAtIndex(phoneNumbers, i));
NSLog(#" phone is:%#", phoneNumber);
}
[array addObject:[NSDictionary dictionaryWithObjectsAndKeys:firstName , #"first_name"
, lastName , #"last_name" ,phoneNumber,#"phone_Number" ,nil]];
NSArray *ar=[[NSArray alloc]init];
NSLog(#"array is,%#",ar);
CFRelease(phoneNumbers);
}
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath
*)indexPath
{
return 50;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (tableView == self.searchDisplayController.searchResultsTableView)
return [filtereditems count];
else
return [array count];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:
(NSIndexPath *)indexPath
{
NSLog(#"array is %#",array);
static NSString *CustomCellID = #"cell";
contactcellTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CustomCellID];
if (cell == nil)
{
cell=[[contactcellTableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:CustomCellID];
NSArray *nib=[[NSBundle mainBundle]loadNibNamed:#"contactcellTableViewCell" owner:self
options:nil];
cell =[nib objectAtIndex:0];
}
if (tableView == self.searchDisplayController.searchResultsTableView) {
cell.Firstnamelbl.text = [filtereditems objectAtIndex:indexPath.row];
cell.Lastnamelbl.text = [filtereditems objectAtIndex:indexPath.row];
} else {
cell.Firstnamelbl.text = [[array
objectAtIndex:indexPath.row]objectForKey:#"first_name"];
cell.Lastnamelbl.text = [[array objectAtIndex:indexPath.row]objectForKey:#"last_name"];
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath
*)indexPath
{
[array removeAllObjects];
contactcellTableViewCell *cell = (contactcellTableViewCell *) [tableView
cellForRowAtIndexPath:indexPath];
static NSString *CustomCellID = #"cell";
NSString *string=[firstName stringByAppendingString:lastName];
if (cell == nil)
{
cell=[[contactcellTableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:CustomCellID];
NSArray *nib=[[NSBundle mainBundle]loadNibNamed:#"contactcellTableViewCell" owner:self
options:nil];
cell =[nib objectAtIndex:0];
}
if (cell.m_checkImageView.image == [UIImage imageNamed:#"Selected.png"])
{
cell.m_checkImageView.image = [UIImage imageNamed:#"Unselected.png"];
}
else
{
cell.m_checkImageView.image = [UIImage imageNamed:#"Selected.png"];
NSLog(#"string is %#",string);
}
}
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
[self.filtereditems removeAllObjects];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF.name contains[c]
%#",searchText];
NSArray *tempArray = [array filteredArrayUsingPredicate:predicate];
if(![scope isEqualToString:#"All"]) {
// Further filter the array with the scope
NSPredicate *scopePredicate = [NSPredicate predicateWithFormat:#"SELF.category
contains[c] %#",scope];
tempArray = [tempArray filteredArrayUsingPredicate:scopePredicate];
}
filtereditems = [NSMutableArray arrayWithArray:tempArray];
}
here is my code and when i am yping any thing in the search bar i cannot able o find the search thing and search bar is not responding at all. please help thanks in advance
Related
I am fetching the contacts of iPhone and make their Dictionary Check my code
-(void) fetchContacts
{
CNContactStore *store = [[CNContactStore alloc] init];
[store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (granted == YES) {
//keys with fetching properties
NSArray *keys = #[CNContactFamilyNameKey, CNContactGivenNameKey, CNContactPhoneNumbersKey, CNContactImageDataKey];
NSString *containerId = store.defaultContainerIdentifier;
NSPredicate *predicate = [CNContact predicateForContactsInContainerWithIdentifier:containerId];
NSError *error;
NSArray *cnContacts = [store unifiedContactsMatchingPredicate:predicate keysToFetch:keys error:&error];
if (error) {
NSLog(#"error fetching contacts %#", error);
} else {
NSString *phone;
NSString *fullName;
NSString *firstName;
NSString *lastName;
UIImage *profileImage;
NSMutableArray *contactNumbersArray;
for (CNContact *contact in cnContacts) {
// copy data to my custom Contacts class.
firstName = contact.givenName;
lastName = contact.familyName;
if (lastName == nil) {
fullName=[NSString stringWithFormat:#"%#",firstName];
}else if (firstName == nil){
fullName=[NSString stringWithFormat:#"%#",lastName];
}
else{
fullName=[NSString stringWithFormat:#"%# %#",firstName,lastName];
}
UIImage *image = [UIImage imageWithData:contact.imageData];
if (image != nil) {
profileImage = image;
}else{
profileImage = [UIImage imageNamed:#"acc_sett.png "];
}
for (CNLabeledValue *label in contact.phoneNumbers) {
phone = [label.value stringValue];
if ([phone length] > 0) {
[contactNumbersArray addObject:phone];
}
}
NSDictionary* personDict = [[NSDictionary alloc] initWithObjectsAndKeys: fullName,#"fullName",profileImage,#"userImage",phone,#"PhoneNumbers", nil];
[_Contacts addObject:personDict];
NSLog(#"%#",phone);
NSLog(#"%#",fullName);
}
dispatch_async(dispatch_get_main_queue(), ^{
[self.contacttableview reloadData];
});
}
}
}];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [_Contacts count];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSDictionary* personDict = [_Contacts objectAtIndex:indexPath.row];
UITableViewCell *cell = nil;
cell = [_contacttableview dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"cell"];
}
cell.imageView.image = [personDict objectForKey:#"userImage"];
cell.textLabel.text = [personDict objectForKey:#"fullName"];
cell.detailTextLabel.text = [personDict objectForKey:#"phoneNumbers"];
return cell;
}
With the help of this code Dictionary Data is display on the tableview now i want to pass image fullname and phone number of a person on the another view controller on selecting their row.
I have tried many method but not get any result
In YourViewController.h, create a property of Person that you want to pass
#property (nonatomic, assign) NSDictionary *person;
In TableViewController.m, didSelectRowAtIndexPath:
YourViewController *vc = [[YourViewController alloc] init];
vc.person = [_Contacts objectAtIndex:indexPath.row];
[self.navigationController pushViewController:vc animated:YES];
First create any NSDictionary object or Your model class object on OtherViewController where you want to navigate then write code like Below,
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
OtherViewController *VC = [[OtherViewController alloc] init];
VC.objContactModel = [_Contacts objectAtIndex:indexPath.row];
[self.navigationController pushViewController:VC animated:YES];
}
Hope it will work.
I have a UITableView and his datasource is an NSMutableArray declared in my interface:
#property (strong, nonatomic) NSMutableArray *arrElements;
Now I implemented a simple "load more" in this way:
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
float endScrolling = scrollView.contentOffset.y + scrollView.frame.size.height;
if (endScrolling >= scrollView.contentSize.height)
{
//only if i have others results i will call load more
if([self.items_amount integerValue] > self.arrElements.count) {
if(DEBUG_MODE == 1) {
NSLog(#"Load more");
}
//get start param from array size and call load more
NSNumber *start = [NSNumber numberWithInteger:([self.arrElements count]+1)];
NSArray *passParams = [NSArray arrayWithObjects:self.menuItem,start,[NSNumber numberWithInteger:NUM_RESULTS_FOR_PAGE], nil];
[self performSelector:#selector(loadMore:) withObject:passParams afterDelay:0.1];
}
}
}
and this is my loadMore method:
//load more elements
- (void)loadMore:(NSArray *)arrParams {
//(MenuItem *)menuItem startingFrom:(NSNumber *)start numResults:(NSNumber *)results;
MenuItem *menuItem = [arrParams objectAtIndex:0];
NSNumber *start = [arrParams objectAtIndex:1];
NSNumber *results = [arrParams objectAtIndex:2];
if(DEBUG_MODE == 1) {
NSLog(#"Before load more %lu", (unsigned long)[self.arrElements count]);
}
//call API and parse it
WebServicesClient *restClient = [[WebServicesClient alloc] init];
NSData *data = [restClient callWorkAPI:[menuItem pathAPI] inLanguage:[[NSLocale preferredLanguages] objectAtIndex:0] withLat:self.latitude withLng:self.longitude startingFrom:start numRows:results];
for(Work* work in [[restClient parseWorks:data] objectForKey:#"items"]) {
[self.arrElements addObject:work];
}
if(DEBUG_MODE == 1) {
NSLog(#"After load more %lu", (unsigned long)[self.arrElements count]);
}
[self.tableElem reloadData];
}
And this is my custom cell:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier;
CellIdentifier = #"HomeCell";
HomeCell *cell = (HomeCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(!cell) {
cell = [[HomeCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
Work *work = (Work *)[[self arrElements] objectAtIndex:indexPath.row];
cell.backgroundColor = [UIColor clearColor];
cell.labelTitleItem.text = [work title];
cell.labelSubtitleItem.text = #"my category"
//if exists image
if([[work image] isKindOfClass:[NSString class]] && [[work image] length] > 0) {
dispatch_async(dispatch_get_global_queue(0,0), ^{
NSData * data = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString:[work image]]];
if ( data == nil )
return;
dispatch_async(dispatch_get_main_queue(), ^{
cell.imageItem.image = [UIImage imageWithData: data];
});
});
} else {
//remove image setting height to 0
[cell.imageItem setFrame:CGRectMake(cell.imageItem.frame.origin.x, cell.imageItem.frame.origin.y, cell.imageItem.frame.size.width, 0)];
}
if([[work distance] isKindOfClass:[NSString class]]) {
[cell.imagePriority setBackgroundColor:[UIColor lightGrayColor]];
cell.labelDistanceItem.text = [self convertDistance:[work distance]];
cell.labelDistanceItem.textColor = [UIColor whiteColor];
} else {
//remove image setting height to 0
[cell.imagePriority setFrame:CGRectMake(cell.imagePriority.frame.origin.x, cell.imagePriority.frame.origin.y, cell.imagePriority.frame.size.width, 0)];
//remove label distance setting height to 0
[cell.labelSubtitleItem setFrame:CGRectMake(cell.labelSubtitleItem.frame.origin.x, cell.labelSubtitleItem.frame.origin.y, cell.labelSubtitleItem.frame.size.width, 0)];
}
return cell;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [[self arrElements] count];
}
Now the problem is that after reloadData i lose the text of a UILabel (my category) of my CustomCell
please, Any suggests?
I've had similar problems with TalbeViews. Try using the method
- (void) tableView:(UITableView *)tableView willDisplayCell:(RCGameTableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
to add the elements that you want. Keep the cell initialization that you do at the beginning of cellForRowAtIndexPath, but then return the cell right after and set the background color, labels, images, etc. in the willDisplayCell delegate function I mentioned.
My iOS app populates an SQLlite database (using FMDB) from a web query. There is a UITableView to display this data. Since I started writing the app the size of this db has exploded to about 10,000 records.
My current design is to load the data in an array from the db and then use that in the UITableView. It works, and I have the alphabetized index on the right hand side of the screen for the user to quickly access the data.
The problem of course is it takes 15-20 seconds to load the array. I originally designed this to load every time the user hits the UITableView, but that means 15-20 seconds every time.
Is there a way to only load some of the data in the UITableView while keeping the search functionality and the index?
Can/should I load the array once and reuse it? I have tried but I can't seem to get that work.
As a last resort, I could switch to CoreData but I really don't want to switch horses in midstream.
UITableView implementation:
#import "ContactViewController.h"
#import "ContactDetailViewController.h"
#interface ContactViewController ()
#end
#implementation ContactViewController {
NSMutableArray *_contacts;
UISearchDisplayController *searchController;
BOOL isSearching;
}
- (void)awakeFromNib {
if ([[UIDevice currentDevice] userInterfaceIdiom] ==
UIUserInterfaceIdiomPad) {
self.clearsSelectionOnViewWillAppear = NO;
self.preferredContentSize = CGSizeMake(320.0, 600.0);
}
[super awakeFromNib];
}
- (void)viewDidLoad {
[super viewDidLoad];
// Get array of employees and sections
_contacts = [ContactsDatabase getContacts];
self.sections = [ContactsDatabase getSections:_contacts];
// Set up Search
self.searchDisplayController.displaysSearchBarInNavigationBar = YES;
self.filteredContacts = [NSMutableArray array];
searchController.delegate = self;
searchController.searchResultsDataSource = self;
isSearching = FALSE;
// iPad
// self.dtailViewController = (detailViewController
// *)[[self.splitViewController.viewControllers lastObject]
// topViewController];
// Set the back bar button
UIBarButtonItem *backButton =
[[UIBarButtonItem alloc] initWithTitle:#"Contacts"
style:UIBarButtonItemStylePlain
target:nil
action:nil];
self.navigationItem.backBarButtonItem = backButton;
}
#pragma mark - Table View
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section {
NSInteger tmpRows;
if (tableView == self.searchDisplayController.searchResultsTableView) {
tmpRows = [self.filteredContacts count];
} else {
tmpRows = [[self.sections
valueForKey:[[[self.sections allKeys]
sortedArrayUsingSelector:
#selector(localizedCaseInsensitiveCompare:)]
objectAtIndex:section]] count];
}
return tmpRows;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell =
[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
}
if (isSearching) {
contact *thisContact = [self.filteredContacts objectAtIndex:indexPath.row];
cell.textLabel.text = thisContact.cmpNme;
} else {
contact *thisContact = [[self.sections
valueForKey:[[[self.sections allKeys]
sortedArrayUsingSelector:
#selector(localizedCaseInsensitiveCompare:)]
objectAtIndex:indexPath.section]]
objectAtIndex:indexPath.row];
cell.textLabel.text = thisContact.cmpNme;
}
return cell;
}
#pragma mark - Table Sections
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
NSInteger tmpCount;
if (isSearching) {
tmpCount = 1;
} else {
tmpCount = [[self.sections allKeys] count];
}
return tmpCount;
}
- (NSString *)tableView:(UITableView *)tableView
titleForHeaderInSection:(NSInteger)section {
NSString *tmpString;
if (tableView == self.searchDisplayController.searchResultsTableView) {
tmpString = nil;
} else {
tmpString = [[[self.sections allKeys]
sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)]
objectAtIndex:section];
}
return tmpString;
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"showContactDetail"]) {
contact *dtlContact;
if (isSearching) {
dtlContact = [self.filteredContacts
objectAtIndex:self.searchDisplayController.searchResultsTableView
.indexPathForSelectedRow.row];
} else {
dtlContact = [[self.sections
valueForKey:[[[self.sections allKeys]
sortedArrayUsingSelector:
#selector(localizedCaseInsensitiveCompare:)]
objectAtIndex:[self.tableView indexPathForSelectedRow]
.section]]
objectAtIndex:[self.tableView indexPathForSelectedRow].row];
}
self.contactDetailViewController.detailItem = dtlContact;
[[segue destinationViewController] setDetailItem:dtlContact];
}
}
#pragma mark - Right side bar alphabetical index
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
NSArray *tmpTitle;
if (isSearching) {
tmpTitle = nil;
} else {
tmpTitle = [[self.sections allKeys]
sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
}
return tmpTitle;
}
#pragma mark - Search methods
- (void)searchDisplayControllerWillBeginSearch:
(UISearchDisplayController *)controller {
isSearching = TRUE;
self.searchDisplayController.searchBar.showsCancelButton = YES;
[self.tableView reloadSectionIndexTitles];
}
- (void)searchDisplayControllerDidEndSearch:
(UISearchDisplayController *)controller {
isSearching = FALSE;
self.searchDisplayController.searchBar.showsCancelButton = NO;
[self.tableView reloadSectionIndexTitles];
}
- (void)filterContentForSearchText:(NSString *)searchText
scope:(NSString *)scope {
[self.filteredContacts removeAllObjects];
NSPredicate *predicate =
[NSPredicate predicateWithFormat:#"cmpNme contains[c] %#", searchText];
NSArray *tempArray = [_contacts filteredArrayUsingPredicate:predicate];
// Move to filtered array
self.filteredContacts = [NSMutableArray arrayWithArray:tempArray];
self.sections = [ContactsDatabase getSections:_contacts];
}
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller
shouldReloadTableForSearchString:(NSString *)searchString {
isSearching = TRUE;
[self
filterContentForSearchText:searchString
scope:[self.searchDisplayController.searchBar
.scopeButtonTitles
objectAtIndex:
self.searchDisplayController.searchBar
.selectedScopeButtonIndex]];
return YES;
}
#end
getContacts methods
+ (NSMutableArray *)getContacts {
id tmpDatabasePath = [(AppDelegate *)
[[UIApplication sharedApplication] delegate] databasePathContacts];
NSMutableArray *tmpContacts;
tmpContacts = [[NSMutableArray alloc] init];
FMDatabase *db = [FMDatabase databaseWithPath:tmpDatabasePath];
[db open];
FMResultSet *results =
[db executeQuery:#"SELECT * FROM contacts ORDER by cmpNme"];
while ([results next]) {
contact *thisContact = [contact new];
thisContact.cmpNme = [results stringForColumn:#"cmpNme"];
thisContact.fstNme = [results stringForColumn:#"fstNme"];
thisContact.lstNme = [results stringForColumn:#"lstNme"];
thisContact.cntTyp = [results stringForColumn:#"cnttyp"];
NSString *tst = [results stringForColumn:#"phnNbr"];
thisContact.phnNbr = [NSNumber numberWithInt:[tst intValue]];
thisContact.adr1 = [results stringForColumn:#"adr1"];
thisContact.adr2 = [results stringForColumn:#"adr2"];
thisContact.cty = [results stringForColumn:#"cty"];
thisContact.ste = [results stringForColumn:#"ste"];
tst = [results stringForColumn:#"zip"];
thisContact.zip = [NSNumber numberWithInt:[tst intValue]];
thisContact.ema = [results stringForColumn:#"ema"];
tst = [results stringForColumn:#"id"];
thisContact.id = [NSNumber numberWithInt:[tst intValue]];
[tmpContacts addObject:thisContact];
}
[db close];
return tmpCon
I have a simple view which has been successfully loading a table of data from CoreData for the last 18 months. It even works now on devices that have been upgraded to IOS 7. But when I upgraded to Xcode5 and run through the IOS7 3.5inch retina simulator my table is always empty. I have pasted my code below and I can confirm that the fetchRequests are returning the data because I can see this in the NSLog outputs. But why has be table stopped populating the cells?
I feel really stupid because I just cannot figure this one out…
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSLog(#"listData count in numberOFRowsInSection is: %i", listData.count);
return [self.listData count];
}
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
Sessions *info = [_fetchedResultsController objectAtIndexPath:indexPath];
NSLog(#"info content is: %#", info.sport);
//Format cell data ready to be displayed
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"EE, dd LLL yyyy"];
NSString *dateString = [dateFormat stringFromDate:info.date];
NSNumber *dist1Nbr = info.dist1;
int dist1Int = [dist1Nbr integerValue];
float distIntKorM = ([dist1Nbr integerValue])/1000;
NSString *dist1StrMeters = [[NSString alloc] initWithFormat:#"%i", dist1Int];
NSString *dist1StrKorM = [[NSString alloc] initWithFormat:#"%.01f", distIntKorM];
//Select image to display
if ([info.sport isEqualToString:#"Run"]) {
UIImage *image = [UIImage imageNamed:#"trainers-15x10.png"];
cell.imageView.image = image;
cell.textLabel.text = [[NSString alloc] initWithFormat:#"%#: (%#),", dateString, info.sport];
cell.detailTextLabel.text = [[NSString alloc] initWithFormat:#"Type: %#, Dist: %#", info.sessiontype, dist1StrKorM];
NSLog(#"Cell text for Runs shoudl be: %#", cell.textLabel.text);
} else if ([info.sport isEqualToString:#"Other"]) {
UIImage *image = [UIImage imageNamed:#"weights-15x10.png"];
cell.imageView.image = image;
cell.textLabel.text = [[NSString alloc] initWithFormat:#"%#: (%#),", dateString, info.sport];
cell.detailTextLabel.text = [[NSString alloc] initWithFormat:#"Type: %#, Dist: %#", info.sessiontype, dist1StrKorM];
} else if ([info.sport isEqualToString:#"Swim"]) {
UIImage *image = [UIImage imageNamed:#"goggles-15x10.png"];
cell.imageView.image = image;
cell.textLabel.text = [[NSString alloc] initWithFormat:#"%#: (%#),", dateString, info.sport];
cell.detailTextLabel.text = [[NSString alloc] initWithFormat:#"Type: %#, Dist: %#m", info.sessiontype, dist1StrMeters];
NSLog(#"Cell text for Swims shoudl be: %#", cell.textLabel.text);
} else if ([info.sport isEqualToString:#"Cycle"]) {
UIImage *image = [UIImage imageNamed:#"bike-15x10.png"];
cell.imageView.image = image;
cell.textLabel.text = [[NSString alloc] initWithFormat:#"%#: (%#),", dateString, info.sport];
cell.detailTextLabel.text = [[NSString alloc] initWithFormat:#"Type: %#, Dist: %#", info.sessiontype, dist1StrKorM];
} else if ([info.sport isEqualToString:#"Brick"]) {
UIImage *image = [UIImage imageNamed:#"brick-15x10.png"];
cell.imageView.image = image;
cell.textLabel.text = [[NSString alloc] initWithFormat:#"%#: (%#),", dateString, info.sport];
cell.detailTextLabel.text = [[NSString alloc] initWithFormat:#"Type: %#, Dist: %#", info.sessiontype, dist1StrKorM];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"editSession";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
// this cell backgrond colour alternating works!
UIView *bgColor = [cell viewWithTag:100];
if (!bgColor) {
CGRect frame = CGRectMake(0, 0, 320, 50);
bgColor = [[UIView alloc] initWithFrame:frame];
bgColor.tag = 100;
[cell addSubview:bgColor];
[cell sendSubviewToBack:bgColor];
}
if (indexPath.row % 2 == 0) {
bgColor.backgroundColor = [UIColor colorWithRed:233.0/255.0 green:233.0/255.0 blue:233.0/255.0 alpha:1.0];
} else {
bgColor.backgroundColor = [UIColor clearColor]; }
[self configureCell:cell atIndexPath:indexPath];
return cell;
}
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
if (_context == nil)
{
_context = [(SGK_T4T_01AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
NSLog(#"After managedObjectContext: %#", _context);
}
NSError *error;
if (![[self fetchedResultsController] performFetch:&error]) {
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
exit(-1);
} else {
NSLog(#"After fetchedResultsController: %#", _fetchedResultsController);
//NSLog(#"After managedObjectContext: %#", _fetchedResultsController);
}
self.title = #"Sessions";
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
[self setListData:nil];
[self setSelectedSession:nil];
[self setSessionSport:nil];
//[self setRecordCount:nil];
[self setFetchedResultsController:nil];
[self setContext:nil];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
SGK_T4T_01AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [appDelegate managedObjectContext];
NSEntityDescription *entityDiscription = [NSEntityDescription entityForName:#"Sessions" inManagedObjectContext:context];
//NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"refid" ascending:YES];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entityDiscription];
NSError *error;
NSArray *objects = [context executeFetchRequest:request error:&error];
if (objects == nil) {
NSLog(#"The fetch request returned an array == nil");
} else {
NSLog(#"The fetch request returned an array!!!");
NSLog(#"objects contents is: %#", objects);
NSLog(#"objects count = %i", [objects count]);
listData = objects;
NSLog(#"listData count = %i", [listData count]);
//NSUInteger *recordCount = [objects count];
recordCount = [objects count];
}
//reload tableView:dataSource from CoreData when view reappears...
if (_context == nil)
{
_context = [(SGK_T4T_01AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
NSLog(#"After managedObjectContext: %#", _context);
}
NSError *error1;
if (![[self fetchedResultsController] performFetch:&error1]) {
NSLog(#"Unresolved error %#, %#", error1, [error1 userInfo]);
exit(-1);
} else {
NSLog(#"viewWillAppear: fetchedResultsController: %#", _fetchedResultsController);
}
//end of reload tableView:dataSource from CoreData when view reappears...
[self.tableView reloadData];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
//[self setFetchedResultsController:nil];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
//[self setFetchedResultsController:nil];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
//#warning Potentially incomplete method implementation.
// Return the number of sections.
return 1;
}
/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
*/
// 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
[_context deleteObject:[self.fetchedResultsController objectAtIndexPath:indexPath]];
NSError *error = nil;
if (![_context save:&error]) {
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
} 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
}
[self.tableView reloadData];
}
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath
{
if (type == NSFetchedResultsChangeDelete) {
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
NSUInteger index = indexPath.row;
//NSLog(#" Prep4Seg indexPath.row = %u", index);
//NSLog(#" Prep4Seg recordCount = %u", recordCount);
/*
Subtract the row index from the row count to get the correct position in the Array (because I am sorting on date order so tableCell position 0 is position 2 in the Array (if there are 3 only items in the table and array) so if you don't invert the indexPath you end up passing the last item instead of the first or second last item instead of the second and so on...
*/
NSUInteger arrayIndex = (recordCount-index-1);
//NSLog(#" Prep4Seg arrayIndex = %u", arrayIndex);
selectedSession = [listData objectAtIndex:arrayIndex];
//NSLog(#"listData = %#", listData);
//NSLog(#"SelectedSession = %#", selectedSession);
NSNumber *refId = [selectedSession valueForKey:#"refid"];
NSString *refIdToSend = [[NSString alloc] initWithFormat:#"%#", refId];
NSLog(#"Prep4Seg in tableView: refIdToSend = %#", refIdToSend);
if ([segue.identifier isEqualToString:#"editSession"]) {
SGK_T4T_EditSessionDetail *editSessionDetail = segue.destinationViewController;
editSessionDetail.delegate = (id)self;
editSessionDetail.returnFromDatePickerView = [[NSString alloc] initWithFormat:#"no"];
editSessionDetail.recedIndex = refIdToSend;
}
}
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
// The fetch controller is about to start sending change notifications, so prepare the table view for updates.
[self.tableView beginUpdates];
}
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {
switch(type) {
case NSFetchedResultsChangeInsert:
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
// The fetch controller has sent all current change notifications, so tell the table view to process all updates.
[self.tableView endUpdates];
}
And my log output is:
2013-11-09 16:04:04.034 trainForTri copy[6509:a0b] After managedObjectContext: <NSManagedObjectContext: 0xb589bc0>
2013-11-09 16:04:04.036 trainForTri copy[6509:a0b] After fetchedResultsController: <NSFetchedResultsController: 0xb5e2c40>
2013-11-09 16:04:04.040 trainForTri copy[6509:a0b] The fetch request returned an array!!!
2013-11-09 16:04:04.041 trainForTri copy[6509:a0b] objects contents is: (
"<NSManagedObject: 0xb5c8570> (entity: Sessions; id: 0xb5ac970 <x-coredata://B93EE0DE-E6FA-491C-9C8F-23692A36DD0C/Sessions/p1> ; data: <fault>)",
"<NSManagedObject: 0xb5d6320> (entity: Sessions; id: 0xb58a2a0 <x-coredata://B93EE0DE-E6FA-491C-9C8F-23692A36DD0C/Sessions/p2> ; data: <fault>)",
"<NSManagedObject: 0xb5d0370> (entity: Sessions; id: 0xb5dc270 <x-coredata://B93EE0DE-E6FA-491C-9C8F-23692A36DD0C/Sessions/p3> ; data: <fault>)",
"<NSManagedObject: 0xb5e3dd0> (entity: Sessions; id: 0xb5ebcc0 <x-coredata://B93EE0DE-E6FA-491C-9C8F-23692A36DD0C/Sessions/p4> ; data: <fault>)",
"<NSManagedObject: 0xb585e40> (entity: Sessions; id: 0xb5e4e40 <x-coredata://B93EE0DE-E6FA-491C-9C8F-23692A36DD0C/Sessions/p5> ; data: <fault>)"
)
2013-11-09 16:04:04.041 trainForTri copy[6509:a0b] objects count = 5
2013-11-09 16:04:04.042 trainForTri copy[6509:a0b] listData count = 5
2013-11-09 16:04:04.043 trainForTri copy[6509:a0b] viewWillAppear: fetchedResultsController: <NSFetchedResultsController: 0xb5a01e0>
2013-11-09 16:04:04.043 trainForTri copy[6509:a0b] listData count in numberOFRowsInSection is: 5
OK, found the issue with this. Eventually after almost wanting to throw my Macbook out of the window in frustration with Xcode5 I shut everything down and restarted. when I opened Xcode, built and ran my App it lo longer loaded an empty table - it now produced an error which indicated that there was something wrong with my NSFetchedResultsController. I traced it to an issue with the cache not clearing (or not being mutable) - so I removed the cache name and set it to nil and everything is working again. I am not sure if this is an IOS7/Xcode5 issue but it has not been a problem until this upgrade. For anyone searching for a similar fix here is the offending line of code:
NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:_context sectionNameKeyPath:nil cacheName:#"Root"];
And this is the version that works!
NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:_context sectionNameKeyPath:nil cacheName:nil];
I hope I'm not the only one ever to struggle with this and therefore just a thickie!
For some reason NSPredicate isn't filtering my UITableView (it's supposed to be filtering my TableView by selections made in a UIPickerView). Users make their pickerview selections, press the GO button (segue is attached from Pickerview to Table View controller).
Any idea as to why it isn't working? See code below.
ViewController.m (TABLE VIEW CONTROLLER)
- (int)numberOfSectionsInTableView: (UITableView *)tableview
{
return 1;
}
- (int)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (tableView == self.searchDisplayController.searchResultsTableView) {
return [searchResults count];
} else {
return [Strains count];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *strainTableIdentifier = #"StrainTableCell";
StrainTableCell *cell = (StrainTableCell *)[tableView dequeueReusableCellWithIdentifier:strainTableIdentifier];
if (cell == nil)
cell = [[StrainTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:strainTableIdentifier];
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"StrainTableCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
if (tableView == self.searchDisplayController.searchResultsTableView) {
NSLog(#"Using the search results");
cell.titleLabel.text = [[searchResults objectAtIndex:indexPath.row] objectForKey:#"Title"];
cell.descriptionLabel.text = [[searchResults objectAtIndex:indexPath.row] objectForKey:#"Description"];
cell.ratingLabel.text = [[searchResults objectAtIndex:indexPath.row] objectForKey:#"Rating"];
cell.ailmentLabel.text = [[searchResults objectAtIndex:indexPath.row] objectForKey:#"Ailment"];
cell.actionLabel.text = [[searchResults objectAtIndex:indexPath.row] objectForKey:#"Action"];
cell.ingestLabel.text = [[searchResults objectAtIndex:indexPath.row] objectForKey:#"Ingestion"];
NSLog(#"%#", searchResults);
} else {
NSLog(#"Using the FULL LIST!!");
cell.titleLabel.text = [[Strains objectAtIndex:indexPath.row] objectForKey:#"Title"];
cell.descriptionLabel.text = [[Strains objectAtIndex:indexPath.row] objectForKey:#"Description"];
cell.ratingLabel.text = [[Strains objectAtIndex:indexPath.row] objectForKey:#"Rating"];
cell.ailmentLabel.text = [[Strains objectAtIndex:indexPath.row] objectForKey:#"Ailment"];
cell.actionLabel.text = [[Strains objectAtIndex:indexPath.row] objectForKey:#"Action"];
cell.ingestLabel.text = [[Strains objectAtIndex:indexPath.row] objectForKey:#"Ingestion"];
}
return cell;
}
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
NSPredicate *resultPredicate = [NSPredicate
predicateWithFormat:#"Title contains[cd] %#",
searchText];
searchResults = [Strains filteredArrayUsingPredicate:resultPredicate];
}
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller
shouldReloadTableForSearchString:(NSString *)searchString
{
[self filterContentForSearchText:searchString
scope:[[self.searchDisplayController.searchBar scopeButtonTitles]
objectAtIndex:[self.searchDisplayController.searchBar
selectedScopeButtonIndex]]];
return YES;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
StrainDetailViewController *detailViewController = [[StrainDetailViewController alloc] initWithNibName:#"StrainDetailViewController" bundle:nil]; if ([searchResults count]) {
detailViewController.title = [[searchResults objectAtIndex:indexPath.row] objectForKey:#"Title"];
detailViewController.strainDetail = [searchResults objectAtIndex:indexPath.row];
} else {
detailViewController.title = [[Strains objectAtIndex:indexPath.row] objectForKey:#"Title"];
detailViewController.strainDetail = [Strains objectAtIndex:indexPath.row];
NSLog(#"%#", Strains);
}
[self.navigationController pushViewController:detailViewController animated:YES];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)PickerViewControllerDidFinish:(PickerViewController *)viewController {
[self.navigationController popViewControllerAnimated:YES];
}
PickerViewController.h
#protocol PickerViewControllerDelegate;
#interface PickerViewController : UIViewController {
UIPickerView *pickerView;
NSMutableArray *array1;
NSMutableArray *array2;
NSMutableArray *array3;
NSArray *Strains;
NSArray *searchResults;
NSMutableData *data;
}
- (IBAction)buttonpressed:(UIButton *)sender;
#property (nonatomic, weak) id<PickerViewControllerDelegate> delegate;
#property (nonatomic, retain) IBOutlet UIPickerView *pickerView;
- (void)populateArray1;
- (void)populateArray2;
- (void)populateArray3;
#end
#protocol PickerViewControllerDelegate <NSObject>
- (void)PickerViewControllerDidFinish:(PickerViewController*)viewController;
#end
PickerViewController.m
#pragma mark -
#pragma mark picker view methods
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView;
{
return 3;
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
if (component == 0)
{
NSLog(#"you selected %#", [array1 objectAtIndex:row]);
}
if (component == 1)
{
NSLog(#"you selected %#", [array2 objectAtIndex:row]);
}
if (component == 2)
{
NSLog(#"you selected %#", [array3 objectAtIndex:row]);
}
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component;
{
if (component == 0)
{
return [array1 count];
}
if (component == 1)
{
return [array2 count];
}
if (component == 2)
{
return [array3 count];
}
else
{
return [array1 count];
}
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component;
{
if (component == 0)
{
return [array1 objectAtIndex:row];
}
if (component == 1)
{
return [array2 objectAtIndex:row];
}
if (component == 2)
{
return [array3 objectAtIndex:row];
}
else
{
return [array2 objectAtIndex:row];
}
}
- (void)populateArray1
{
array1 = [[NSMutableArray alloc] init];
[array1 addObject:#"Arthritis"];
[array1 addObject:#"Cancer"];
[array1 addObject:#"HIV"];
[array1 addObject:#"Migraines"];
[array1 addObject:#"Insomnia"];
}
- (void)populateArray2
{
array2 = [[NSMutableArray alloc] init];
[array2 addObject:#"Nausea"];
[array2 addObject:#"Pain"];
[array2 addObject:#"Appetite"];
[array2 addObject:#"Fever"];
[array2 addObject:#"Exhaustion"];
}
- (void)populateArray3
{
array3 = [[NSMutableArray alloc] init];
[array3 addObject:#"Oil"];
[array3 addObject:#"Plant"];
[array3 addObject:#"Edible"];
[array3 addObject:#"Powder"];
}
- (IBAction)buttonpressed:(UIButton *)sender {
NSLog(#"Button Pushed!");
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Make sure your segue name in storyboard is the same as this line
if ([[segue identifier] isEqualToString:#"pickerGo"])
{
// Get reference to the destination view controller
ViewController *strainTableView = [(UINavigationController *)[segue destinationViewController] topViewController];
NSPredicate *ailmentPredicate = [NSPredicate predicateWithFormat:#"Ailment contains[cd] %#", [pickerView selectedRowInComponent:0]];
NSPredicate *actionPredicate = [NSPredicate predicateWithFormat:#"Action contains[cd] %#", [pickerView selectedRowInComponent:1]];
NSPredicate *ingestPredicate = [NSPredicate predicateWithFormat:#"Ingestion contains[cd] %#", [pickerView selectedRowInComponent:2]];
NSCompoundPredicate *resultPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects: ailmentPredicate,actionPredicate,ingestPredicate, nil]];
searchResults = [Strains filteredArrayUsingPredicate:resultPredicate];
// Pass any objects to the view controller here, like...
[strainTableView setSearchResults: searchResults];
}
}
Very puzzling, your code actually seems ok to me. I'd start by NSLoging searchResults right after the searchResults = [Strains filteredArrayUsingPredicate:resultPredicate]; line is fired, just in case something funny is happening in the table view delegates.
You should also probably check out the free Sensible TableView framework, as it provides automatic searching and filtering for your data. Should save you a ton of time.
It seems your Strains array contains dictionaries. So you should decide on what key you want to filter, for example the Title key, instead of using SELF:
NSPredicate *resultPredicate = [NSPredicate
predicateWithFormat:#"Title contains[cd] %#",
searchText];
From the pickerViewController, you need to go back to the tableViewController. You can use delegate. And try to make a separate function in the table view controller to filter which contains the predicate:
- (void)filterContentForPicker:(NSString*)searchText
{
NSPredicate *resultPredicate = [NSPredicate
predicateWithFormat:#"Title contains[cd] %#",
searchText];
searchResults = [Strains filteredArrayUsingPredicate:resultPredicate];
[self.tableView reloadData]
}