Would you please tell me why my SearchBar doesn´t work in my UITableViewController?
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
NSPredicate *predicate = [NSPredicate
predicateWithFormat:#"SELF.TitleInside contains[c] %#",
searchText];
filteredArray = [HelpList filteredArrayUsingPredicate:predicate];
}
Why
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier =#"Cell";
TableViewCell_Rts *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell){
cell = [[TableViewCell_Rts alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.accessoryType = UITableViewCellAccessoryNone;
CellObject *NewIndex = nil;
if (tableView == self.tableView) {
NewIndex = [HelpList objectAtIndex:indexPath.row];
cell.TitleLabel2.text = NewIndex.TitleInside;
cell.DescriptionLabel2.text = NewIndex.DescriptionInside;
} else {
NewIndex= [filteredArray objectAtIndex:indexPath.row];
cell.TitleLabel2.text = NewIndex.TitleInside;
cell.DescriptionLabel2.text = NewIndex.DescriptionInside;
}
CellObject is a NSObject:
#interface CellObject : NSObject
#property (nonatomic, strong) NSString *ImageInside;
#property (nonatomic, strong) NSString *TitleInside;
#end
When i run the application, my tableview looks populated. Then, when i write inside the search bar, the table doesn´t show the results of the search.
Thanks ¡
Related
I am new in IOS and I am creating a search bar for UITableView. It is working fine when I use an array directly, but when I have an array with a dictionary it's not working.
I have an array of dictionaries:
- (void)viewDidLoad {
[super viewDidLoad];
NSMutableDictionary *person1 = [NSMutableDictionary dictionaryWithDictionary:#{
#"Name" : #"john",
#"Age" : #"10"
}];
NSMutableDictionary *person2 = [NSMutableDictionary dictionaryWithDictionary:#{
#"Name" : #"piter",
#"Age" : #"22"
}];
NSMutableDictionary *person3 = [NSMutableDictionary dictionaryWithDictionary:#{
#"Name" : #"rams",
#"Age" : #"23"
}];
self.person = [[NSMutableArray alloc]initWithObjects:person1,person2,person3 ,nil];
}
I have print those dictionary name on UITableView.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *simpleTableIdentifier = #"myCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.textLabel.text = [[self.personobjectAtIndex:indexPath.row]objectForKey:#"Name"];
return cell;
}
It will give me list of names in UITableView. I used a search bar and I want to search for specific words and have them show on my UITableView, but its not working using this code:
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText{
if([searchText length] == 0){
self.isfiltered = NO;
}
else{
self.isfiltered = YES;
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:#"SELF contains[cd] %#",searchText];
filteredList = [self.person filteredArrayUsingPredicate:resultPredicate];
}
[self.mytable reloadData];
}
You need to change your data source array while searching .
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return self.isfiltered ? filteredList.count : self.person.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *simpleTableIdentifier = #"myCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier]; }
cell.textLabel.text = [[ self.isfiltered ? filteredList : self.person objectAtIndex:indexPath.row]objectForKey:#"Name"]; }
return cell;
}
you need to change 'SELF' -> 'Name'.
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText{
if([searchText length] == 0){
self.isfiltered = NO;
}
else{
self.isfiltered = YES;
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:#"Name contains[cd] %#",searchText];
filteredList = [self.person filteredArrayUsingPredicate:resultPredicate];
}
[self.mytable reloadData];
}
Then change in your table array.
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
if (self.isfiltered)
return filteredList.count;
else
return self.person.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *simpleTableIdentifier = #"myCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier]; }
if (self.isfiltered)
cell.textLabel.text = [[self.isfiltered objectAtIndex:indexPath.row]objectForKey:#"Name"];
else
cell.textLabel.text = [[self.person objectAtIndex:indexPath.row]objectForKey:#"Name"];
return cell;
}
I have an example of UITableViewCell as below:
//
// ItemTableViewCell.h
//
#import <UIKit/UIKit.h>
#interface ItemTableViewCell : UITableViewCell
#property (weak, nonatomic) NSString *itemId;
#end
In my UIViewController with UITableView I have the below assigning :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSManagedObject *row = [self.itemsFRC objectAtIndexPath:indexPath];
ItemTableViewCell *cell = (ItemTableViewCell *)[self.tableView dequeueReusableCellWithIdentifier:#"cellId" forIndexPath:indexPath];
cell.itemId = [row valueForKey:#"item_id"];
}
Now, how can I scroll to specific cell in UITableView with it's cell property itemId?
Note: I highly prefer to not to use indexPathForRow method.
You should do the following:
Find NSManagedObject by item_id
Get indexPath of found object from NSFetchedResultsController
Scroll tableView to that indexPath
See code example below:
- (void) scrollToRowWithItemID: (NSString *) itemID {
NSArray *fetchedObjects = self.itemsFRC.fetchedObjects;
NSPredicate *predicate = [NSPredicate predicateWithFormat: #"item_id == %#", itemID];
NSArray *filteredArray = [fetchedObjects filteredArrayUsingPredicate: predicate];
NSIndexPath *indexPath = [self.itemsFRC indexPathForObject: filteredArray.firstObject];
[self.tableView scrollToRowAtIndexPath: indexPath atScrollPosition: UITableViewScrollPositionNone animated: true];
}
I have four array videoName, ActorName, VideoID, ActorID. I combined videoName & ActorName to make a single array "title", and same with VideoID & ActorID to make array "IDs"
In short,
title = ActorName + videoName
IDs = ActorID + VideoID
here is my code,
Tableview Methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (tableView == self.searchDisplayController.searchResultsTableView) {
return self.searchResults.count;
} else {
return self.title.count;
}
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellID = #"cellID";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID];
}
cell.backgroundColor = [UIColor clearColor];
cell.textLabel.textColor = [UIColor whiteColor];
cell.imageView.frame = CGRectMake(0,0,32,32);
if (tableView == self.searchDisplayController.searchResultsTableView) {
cell.textLabel.text = [self.searchResults objectAtIndex:indexPath.row];
cell.imageView.image = [UIImage imageNamed:[img objectAtIndex:indexPath.row]];
cell.textLabel.textColor = [UIColor blackColor];
} else {
cell.textLabel.text = [self.title objectAtIndex:indexPath.row];
cell.imageView.image = [UIImage imageNamed:[img objectAtIndex:indexPath.row]];
}
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
}
Search Methods
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF beginswith[c] %#", searchText];
// NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:#"contains[c] %#", searchText];
self.searchResults = [self.title filteredArrayUsingPredicate:predicate];
}
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
[self filterContentForSearchText:searchString
scope:[[self.searchDisplayController.searchBar scopeButtonTitles]
objectAtIndex:[self.searchDisplayController.searchBar
selectedScopeButtonIndex]]];
return YES;
}
Requirement
Now, first i need to get that which row was selected, actor or Video, secondly actorID or VideoID. It was easy if there was no search bar, because after the search all rows restored again with new data plus rows are populated from "title" not "IDs" so how can i get IDs when user select the row.
create a NSObject subclass for this Item.h and Item.m with 3 properties for name and id like,
in Item.h
typedef enum : NSInteger {
ItemTypeVideo,
ItemTypeActor,
} ItemType;
#interface Item : NSObject
#property (nonatomic, strong) NSString *name;
#property (nonatomic, strong) NSString *itemId;
#property (nonatomic, strong) NSString *imageName;
#property (nonatomic, assign) ItemType itemType;
#end
by above code we are creating a class whose object can hold values defined in properties.
since an object of Item class can hold name, id, image name and type of video/actor, we can set these values of 1 video/actor to one object.
here we have multiple vides/actor elements, so we need an array of Item objects each one holding details of one video/actor like
Item *videoItem = [[Item alloc] init];
videoItem.name = videoName;
videoItem.itemId = videoId;
videoItem.imageName = videoImageName;
videoItem.itemType = ItemTypeVideo;
create for all items in videoName array and actor array. Add both this to a common dataArray like,
[self.dataArray addObejct:videoItem];
and
Item *actorItem = [[Item alloc] init];
actorItem.name = actorName;
actorItem.itemId = actorId;
actorItem.imageName = actorImageName;
actorItem.itemType = ItemTypeActor;
similarly [self.dataArray addObejct:actorItem];
and in cellForRowAtIndexPath:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//other stuff
Item *currentItem = nil;
if (tableView == self.searchDisplayController.searchResultsTableView) {
currentItem = [self.searchResults objectAtIndex:indexPath.row];
} else {
currentItem = [self.dataArray objectAtIndex:indexPath.row];
}
cell.textLabel.text = currentItem.name;
cell.imageView.image = [UIImage imageNamed:currentItem.imageName];
//rest stuff
}
finally in search,
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"name beginswith[c] %#", searchText];
// NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:#"contains[c] %#", searchText];
self.searchResults = [self.dataArray filteredArrayUsingPredicate:predicate];
}
So in any case,
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
Item *currentItem = nil;
if (tableView == self.searchDisplayController.searchResultsTableView) {
currentItem = [self.searchResults objectAtIndex:indexPath.row];
} else {
currentItem = [self.dataArray objectAtIndex:indexPath.row];
}
//all details will be in currentItem
}
I need to add a search bar for a table view.Table contain "Names" which is actually stored in inside an object called "patient".I have an array of "patient" objects.
So to setup a search bar to search for names.But how to do it using NSPredicate?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString* CellId= #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellId];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellId] ;
}
cell.accessoryType = UITableViewCellAccessoryNone;
ObjPatient = [allPatientDetails objectAtIndex:indexPath.row];
cell.textLabel.text =[NSString stringWithFormat:#"%# %#",ObjPatient.firstName,ObjPatient.lastName];
return cell;
}
Above is the code to show the names on table.
Any suggestions are welcome , Thanks
To Implement search functionality first take look into below links -
https://developer.apple.com/library/ios/documentation/uikit/reference/UISearchBar_Class/Reference.html
https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSPredicate_Class/Reference/NSPredicate.html
Then make changes in your code as follows -
In your .h file declare array -
NSArray *filteredArray;
In - (void)viewDidLoad method -
filteredArray = allPatientDetails;
Then implement UISearchBar delegate method-
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
NSPredicate *predicate = [NSPredicate
predicateWithFormat:#"SELF.firstName contains[c] %#",
searchText];
NSArray *filteredArray = [allPatientDetails filteredArrayUsingPredicate:predicate];
[tableView reloadData];
}
and make changes in your existing method -
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString* identifier= #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier] ;
}
cell.accessoryType = UITableViewCellAccessoryNone;
ObjPatient = [filteredArray objectAtIndex:indexPath.row];
cell.textLabel.text =[NSString stringWithFormat:#"%# %#",ObjPatient.firstName,ObjPatient.lastName];
return cell;
}
well for nspredicate with custom object can be done like this.
NSPredicate *resultPredicate = [NSPredicate
predicateWithFormat:#"SELF.firstName contains[c] %#",
searchText];
self.searchedMemberNameResults = [self.listedMembers filteredArrayUsingPredicate:resultPredicate];
firstName is attribute of an object
Below you can find code for searching an item based on the label in the storyboard. It searches dynamically; I've tested this and it's working.
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:#"job_id contains[c] %#",searchText];
searchResultArray = [responceArray filteredArrayUsingPredicate:resultPredicate];
[jobsTable reloadData];
}
edit: I think the problem is in the last referenced code, because when I try to load the table data instead of the search results (by just swapping the arrays) I still get no search results, but I'm still not sure why... Original post in full:
I'm trying to get a search bar working with my table view. I can enter text in the search bar but always find no results. Here's my .h
#interface SecondViewController : UIViewController <UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate, UISearchDisplayDelegate> {
IBOutlet UISearchBar *searchBar;
NSMutableArray *dummyArray;
NSMutableArray *searchArray;
}
#property (nonatomic, strong) NSMutableArray *dummyArray;
#property (nonatomic, strong) NSMutableArray *searchArray;
#property (nonatomic, strong) NSMutableArray *detailArray;
#property (nonatomic, strong) NSMutableArray *imageArray;
- (void) setupArray;
- (void) setupSearchArray;
- (void) setupDetailArray;
#end
In my .m, dummyArray is the array that fills the main cell.textLabel.text and the array i want to search.
I set up searchArray here:
- (void) setupSearchArray{
searchArray = [NSMutableArray arrayWithCapacity:[dummyArray count]];
}
then attempt to make searchArray a filtered version of dummyArray here:
- (BOOL) searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
[searchArray removeAllObjects] ;
for (NSString *savedSeachTerm in dummyArray) {
NSRange result = [savedSeachTerm rangeOfString:searchString options:
NSCaseInsensitiveSearch];
if (result.location != NSNotFound)
[searchArray addObject:savedSeachTerm];
}
return YES;
}
and try to populate the table with search results when search text is entered here:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
if (tableView == self.searchDisplayController.searchResultsTableView) {
cell.textLabel.text = [searchArray objectAtIndex:indexPath.row];
cell.detailTextLabel.text = [detailArray objectAtIndex:indexPath.row];
}
else {
cell.textLabel.text = [dummyArray objectAtIndex:indexPath.row];
cell.detailTextLabel.text = [detailArray objectAtIndex:indexPath.row];
}
if (indexPath.row == 0) {
cell.imageView.image = [UIImage imageNamed:#"row0.png"];
}
return cell;
}
What have I done wrong? Thanks for looking!
I had forgotten to
[self setupSearchArray];
sorry!