SearchController not searching custom UITableViewCells - ios

Not sure if the title makes to much sense so here is a description of what is going on:
I have a UITableViewController that is using a custom UITableViewCell for its data. I am then manually adding a searchBar to the header of the UITableView and setting it up based on this tutorial : http://useyourloaf.com
Now the searchBar is setup, it looks like it is working but the issue is that I am not actually getting any results and the table is not loading properly (the search results, it load the base data fine)
Here is my code for comparison. I know I must be missing something simple...
** I am hardcoding the data for my cells at the moment, this will change to a core data model once I can fix this issue... although this may be the base of my issue as I am hardcoding the cells at each IP **
#implementation CharitiesTableViewController{
NSArray *charities;
NSArray *searchResults;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self setColors];
[_charityTable registerNib:[UINib nibWithNibName:#"CharityTableViewCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:#"charityCell"];
self.tableView.rowHeight = UITableViewAutomaticDimension;
self.tableView.estimatedRowHeight = 350.0;
// self.tableView.contentInset = UIEdgeInsetsMake(-2.0f, 0.0f, 0.0f, 0.0);
self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
self.searchController.searchResultsUpdater = self;
self.searchController.dimsBackgroundDuringPresentation = NO;
self.searchController.searchBar.delegate = self;
self.searchController.delegate = self;
self.tableView.tableHeaderView = self.searchController.searchBar;
self.definesPresentationContext = YES;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void) setColors {
}
#pragma mark - Search Controller
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController {
NSString *searchString = searchController.searchBar.text;
[self searchForText:searchString];
[self.tableView reloadData];
}
- (void)searchForText:(NSString *)searchText {
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:#"name contains[c] %#", searchText];
searchResults = [charities filteredArrayUsingPredicate:resultPredicate];
}
- (void)willPresentSearchController:(UISearchController *)searchController {
self.navigationController.navigationBar.translucent = YES;
}
-(void)willDismissSearchController:(UISearchController *)searchController {
self.navigationController.navigationBar.translucent = NO;
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
if (tableView == _charityTable)
{
return 1;
}
return [searchResults count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 1;
}
- (CGFloat)tableView:(UITableView*)tableView heightForHeaderInSection:(NSInteger)section {
return SectionSpacer;
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
return SectionSpacer;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
switch (indexPath.section) {
case 0:{
CharityTableViewCell *cell = (CharityTableViewCell *)[tableView dequeueReusableCellWithIdentifier:#"charityCell"];
cell.charityImage.image = [UIImage imageNamed:#"cleanup"];
cell.charityName.text = #"Garbage cleanup - Crowchild";
cell.charityTagLine.text = #"City of Calgary";
cell.charityDescriptionShort.text = #"We are rounding up anyone that wants to help clean up the grass and nearby areas close to crowchild.";
return cell;
}
default:{
UITableViewCell *cell;
return cell;
}
}
}
#end
Thanks for you help!

I am silly.... I was trying to do this without initializing the data like a com mentor said. The code is correct and if anyone has any similar issues make sure your array of data actually has data in it...

Related

How to dismiss UISearchBar once segued

Creating a search view, this is the code that i did for the main search view.
What happens is if i dont search/filter, the uisearchbar gets dismissed when segueing. but if i search/filter then the uisearchbar stays on the nav bar when seguing.
- (void)viewDidLoad {
[super viewDidLoad];
// There's no transition in our storyboard to our search results tableview or navigation controller
// so we'll have to grab it using the instantiateViewControllerWithIdentifier: method
UINavigationController *searchResultsController = [[self storyboard] instantiateViewControllerWithIdentifier:#"CompanySearchResultsNavigationController"];
// Our instance of UISearchController will use searchResults
self.searchController = [[UISearchController alloc] initWithSearchResultsController:searchResultsController];
// The searchcontroller's searchResultsUpdater property will contain our tableView.
self.searchController.searchResultsUpdater = self;
self.searchController.hidesNavigationBarDuringPresentation = NO;
// The searchBar contained in XCode's storyboard is a leftover from UISearchDisplayController.
// Don't use this. Instead, we'll create the searchBar programatically.
self.searchController.searchBar.frame = CGRectMake(self.searchController.searchBar.frame.origin.x, self.searchController.searchBar.frame.origin.y, self.searchController.searchBar.frame.size.width, 44.0);
self.navigationItem.titleView = self.searchController.searchBar;
self.definesPresentationContext = YES;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.objects count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object {
CompanySearchTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"searchCell" forIndexPath:indexPath];
cell.productImageView.file = (PFFile *)object[#"profileImage"];
cell.productImageView.layer.cornerRadius = cell.productImageView.frame.size.width / 2;
cell.productImageView.clipsToBounds = YES;
[cell.productImageView loadInBackground];
cell.companyNameLabel.text = object[#"username"];
return cell;
}
#pragma mark - UISearchControllerDelegate & UISearchResultsDelegate
// Called when the search bar becomes first responder
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController
{
// Set searchString equal to what's typed into the searchbar
NSString *searchString = self.searchController.searchBar.text;
[self updateFilteredContentForAirlineName:searchString];
// If searchResultsController
if (self.searchController.searchResultsController) {
UINavigationController *navController = (UINavigationController *)self.searchController.searchResultsController;
// Present SearchResultsTableViewController as the topViewController
CompanySearchResultsTableViewController *vc = (CompanySearchResultsTableViewController *)navController.topViewController;
// Update searchResults
vc.searchResults = self.searchResults;
// And reload the tableView with the new data
[vc.tableView reloadData];
}
}
// Update self.searchResults based on searchString, which is the argument in passed to this method
- (void)updateFilteredContentForAirlineName:(NSString *)companyName
{
if (companyName == nil) {
// If empty the search results are the same as the original data
self.searchResults = [self.objects mutableCopy];
} else {
NSMutableArray *searchResults = [[NSMutableArray alloc] init];
// Else if the airline's name is
for (PFObject *company in self.objects) {
if ([company[#"username"] containsString:companyName]) {
// NSString *str = [NSString stringWithFormat:#"%#", company[#"username"]];
// [searchResults addObject:str];
PFObject *searchedObject = company;
[searchResults addObject:searchedObject];
NSLog(#"Searched: %#",searchedObject[#"username"]);
}
self.searchResults = searchResults;
}
}
}
In your AirlineTableViewController, override [UIViewController prepareForSegue]:
- (void)prepareForSegue:(UIStoryboardSegue *)segue
sender:(id)sender {
[self.searchController setActive:NO];
}

iOS adding a UISearchController is unhiding the NavigationBar

I am having this weird side effect when I use a UISearchController to update my table view (If I select something from the tableview without searching the bug doesn't manifest itself). But when I search, select a cell, and then popViewControllerAnimated: for some reason the NavigationBar is no longer hidden. I want to think that this is a bug within iOS and not specific to my code. But I thought I would see if anyone can spot a bug in my code or has any ideas of something I might be doing wrong. I've added [self.navigationController setNavigationBarHidden:YES]; to my viewWillAppear of the rootView but the bar doesn't go away until the animation is over.
My TableView/UISearchController code:
#interface LBSelectUniversityView()<UISearchResultsUpdating, UISearchBarDelegate>
#property (strong, nonatomic) UISearchController *searchController;
#end
#implementation LBSelectUniversityView {
NSArray *schoolNames;
NSArray *searchResults;
}
- (void)viewDidLoad {
[super viewDidLoad];
schoolNames = [[LBUtilities sharedInstance] schoolNames];
searchResults = schoolNames;
self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
self.searchController.searchResultsUpdater = self;
self.searchController.dimsBackgroundDuringPresentation = NO;
self.searchController.searchBar.delegate = self;
self.tableView.tableHeaderView = self.searchController.searchBar;
self.definesPresentationContext = YES;
[self.searchController.searchBar sizeToFit];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return searchResults.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];
}
...
return cell;
}
- (void)filterContentForSearchText:(NSString*)searchText{
if ([searchText isEqualToString:#""]) return;
NSPredicate *resultPredicate = [NSPredicate
predicateWithFormat:#"SELF contains[cd] %#",
searchText];
searchResults = [schoolNames filteredArrayUsingPredicate:resultPredicate];
}
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController{
NSString *searchString = searchController.searchBar.text;
[self filterContentForSearchText:searchString];
[self.tableView reloadData];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
...
[self.navigationController popViewControllerAnimated:YES];
}
#end
Does the problem go away if you set searchController.hidesNavigationBarDuringPresentation = NO?
Maybe the following is happening:
When you start searching, searchController.active is set to YES. Thus searchController calls [... setNavigationBarHidden:YES] because UISearchController.hidesNavigationBarDuringPresentation = YES by default.
popViewControllerAnimated: is called.
searchController.active is set to NO, so searchController calls [... setNavigationBarHidden:NO]. This causes the navigation bar to be shown.
I think once your search results comes back you are reloading your main table and not search table. This is how you should load data on search results table.
self.searchController.searchResultsTableView reloadData];

Tableview data won't load when unsegmented control is changed

//The tableview is not changing. I have been at this for days. It seems so simple. Thank you for your help
#import "StopsTableViewController.h"
static NSString *MyIdentifier = #"RouteListing";
#interface StopsTableViewController ()
#property (strong, nonatomic) NSArray *TESTARRAY;
#end
#implementation StopsTableViewController
- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
//Set the tab bar item's title
self.title = #"Stops";
}
self.stopList = [[API sharedAPI] fetchStopListing];
self.TESTARRAY = #[#"Josh", #"Kyle", #"Nate"];
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:MyIdentifier];
// Adds Segmented Control
[self segmentedView];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void) segmentedView {
NSArray *segmentedMenu = [NSArray arrayWithObjects:#"All", #"Near Me", nil];
UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems:segmentedMenu];
[segmentedControl addTarget:self
action:#selector(valueChanged:)
forControlEvents:UIControlEventValueChanged];
segmentedControl.selectedSegmentIndex = 0;
self.navigationItem.titleView = segmentedControl;
}
pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if ([self.segmentedControl selectedSegmentIndex] == 0) {
return [self.stopList count];
}
else {
return [self.TESTARRAY count];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:MyIdentifier];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
if (_segmentedControl.selectedSegmentIndex == 0) {
cell.textLabel.text = [[self.stopList objectAtIndex:indexPath.row] objectForKey:#"stoptitle"];
cell.detailTextLabel.text = [NSString stringWithFormat:#"Stop %#", [[self.stopList objectAtIndex:indexPath.row] objectForKey:#"stopnumber"]];
}
else {
cell.textLabel.text = self.TESTARRAY[indexPath.row];
}
return cell;
}
pragma mark - Table view delegate
// In a xib-based application, navigation from a table can be handled in -tableView:didSelectRowAtIndexPath:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Navigation logic may go here, for example:
// Create the next view controller.
StopInfoViewController *detailViewController = [[StopInfoViewController alloc] initWithNibName:#"StopInfoViewController" bundle:nil];
// Pass the selected object to the new view controller.
detailViewController.stopInfo = [[self.stopList objectAtIndex:indexPath.row] objectForKey:#"stopnumber"];
detailViewController.stopName = [[self.stopList objectAtIndex:indexPath.row] objectForKey:#"stoptitle"];
// Push the view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
}
//Function for segmentedView
-(void) valueChanged:(UISegmentedControl *)sender {
[self.tableView reloadData];
NSLog(#"I'm getting called segment number is: %ld", (long)sender.selectedSegmentIndex);
}
#end
Check your datasource array before calling the table reload method and make sure that the array contains new values corresponding to the segment that you have selected.
One thing I always run into when struggle up a table view is connecting the table with the interface using interface builder. Because it sounds like you're getting the data loaded, when the view first loads. But when you call [self.tableView reloadData] without having the connection made to the table, nothing will happen.
I ways forget that super simple step. Hope this helped
Did you set the tableview delegates?
Try putting this in your viewDidLoad function.
[tableView setDelegate:self];
[tableView setDataSource:self];
If you want a fuller explanation, check here:
how to set a tableview delegate
That post also explains how to ensure your class subscribes to the UITableViewDelegate and UITableViewDataSource protocols
Hope that helps.

UISearchController does not display anything

I have a problem with UISearchController, it is declared in my "FindUsersTableViewController.h" file used to display the searched users.
So, all is in the title, I give you more details with important parts of code of the "FindUsersTableViewController.m" file:
- (void)viewDidLoad {
[super viewDidLoad];
self.searchController = [[UISearchController alloc]initWithSearchResultsController:nil];
self.searchController.dimsBackgroundDuringPresentation = NO;
self.searchController.searchResultsUpdater = self;
self.searchController.delegate = self;
self.searchController.searchBar.frame = CGRectMake(0, 0, 320, 44);
self.tableView.tableHeaderView = self.searchController.searchBar;
self.searchController.searchBar.tintColor = [UIColor blackColor];
self.definesPresentationContext = YES;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.searchResults.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *userCellId = #"userCell";
UserCell *userCell = [tableView dequeueReusableCellWithIdentifier:userCellId forIndexPath:indexPath];
// "self.searchedUser" is a property declared as PFUser in the .h file
PFUser *tempSrchUser = self.searchedUser;
// "self.searchResults" is a property declared as NSMutableArray in the .h file too, it contains the searched users
PFObject *searchedUser = [self.searchResults objectAtIndex:indexPath.row];
NSString *tempUsername = [searchedUser objectForKey:tempSrchUser.username];
userCell.usernameLbl.text = tempUsername;
NSLog(#"retrieved appropriates usernames: %#", userCell.usernameLbl.text);
return userCell;
}
The UISearchController does not display anything... Does anyone knows how to fix that ?
Have you implemented the delegate method - (void)updateSearchResultsForSearchController:(UISearchController *)searchController
? This is required and you need to do the filtering here.

uisearchbar doesn't work

I created a subClass of UITextView with a searchBar, here is the code:
#import "SezioniTableController.h"
#interface SezioniTableController ()
#end
#implementation SezioniTableController
#synthesize searchBar,searchDisplayController;
#synthesize arraySezioni,arrayFiltrato;
#synthesize objTesto;
- (id)initWithStyle:(UITableViewStyle)style andArray:(NSMutableArray *)array{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
self.searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 44)];
self.searchBar.delegate = self;
self.searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:searchBar contentsController:self];
self.searchDisplayController.delegate = self;
self.searchDisplayController.searchResultsDataSource = self;
self.arraySezioni = array;
self.arrayFiltrato = array;
}
return self;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void) loadView {}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return self.arrayFiltrato.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MyIdentifier"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewStylePlain reuseIdentifier:#"MyIdentifier"];
}
self.objTesto = [arrayFiltrato objectAtIndex:indexPath.row];
cell.textLabel.text = self.objTesto.titoloTesto;
return cell;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here. Create and push another view controller.
/*
<#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:#"<#Nib name#>" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
*/
NSDictionary *dict = [NSDictionary dictionaryWithObject:[self.arrayFiltrato objectAtIndex:indexPath.row] forKey:#"Testo"];
[[NSNotificationCenter defaultCenter] postNotificationName:#"PassaggioTesto" object:self userInfo:dict];
NSLog(#"Click");
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
return self.searchBar; //in .h, IBOutlet UISearchBar* search;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 44;
}
- (BOOL) searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString{
[self filterContentForSearchText:searchString scope: [[self.searchDisplayController.searchBar scopeButtonTitles] objectAtIndex:[self.searchDisplayController.searchBar selectedScopeButtonIndex]]];
NSLog(#"aa");
//[[NSNotificationCenter defaultCenter] postNotificationName:#"ReloadTable" object:self];
// Return YES to cause the search result table view to be reloaded.
return YES;
}
- (BOOL) searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption{
[self filterContentForSearchText:[self.searchDisplayController.searchBar text] scope:[[self.searchDisplayController.searchBar scopeButtonTitles] objectAtIndex:searchOption]];
NSLog(#"ab");
//[[NSNotificationCenter defaultCenter] postNotificationName:#"ReloadTable" object:self];
// Return YES to cause the search result table view to be reloaded.
return YES;
}
- (void) filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope{
NSLog(#"a count:%d",self.arraySezioni.count);
[self.arrayFiltrato removeAllObjects]; // First clear the filtered array.
for (objTesto in self.arraySezioni){
NSComparisonResult result = [objTesto.titoloTesto compare:searchText options:NSCaseInsensitiveSearch range:NSMakeRange(0, [searchText length])];
if (result == NSOrderedSame){
NSLog(#"Titolo: %#",objTesto.titoloTesto);
[self.arrayFiltrato addObject:self.objTesto];
}else{
NSLog(#"Non trovato");
}
}
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)saearchBar {
[self.arrayFiltrato removeAllObjects];
[self.arrayFiltrato addObjectsFromArray: self.arraySezioni];
}
#end
On my uiviewcontroller I create a table using the uitableview created with this code:
self.arrayTesti = [self.dataLoad leggiArgomentiDellaSezione:tag];
self.table = [[SezioniTableController alloc] initWithStyle:UITableViewStylePlain andArray:self.arrayTesti];
self.tableArgumentView.delegate = self.table;
self.tableArgumentView.dataSource = self.table;
[self.tableArgumentView reloadData];
The viewcontroller is for an iPad application, the table works perfectly but if I try to search something it doesn't work!
Can you help me?
If you assign
self.arraySezioni = array;
self.arrayFiltrato = array;
then both self.arraySezioni and self.arrayFiltrato are pointers to the same array. Which means that if you empty one array with
[self.arrayFiltrato removeAllObjects];
then the other array self.arraySezioni (and the original array) are also empty.
So at least self.arrayFiltrato should be a copy of the original array:
self.arrayFiltrato = [array copy];

Resources