I'm trying to add a UISearchBar to a UITableView but the method TextDidBeginEditing is not being called. I think I am missing something simple but I can't figure it out.
Header File:
#interface TableViewController : UITableViewController <UITableViewDataSource, UITableViewDelegate, UISearchBarDelegate>
#property (nonatomic, strong) NSMutableArray *initialCities;
#property (nonatomic, strong) NSMutableArray *filteredCities;
#property (nonatomic, strong) UISearchBar *searchBar;
#property BOOL isFiltered;
#end
Implementation File:
#import "TableViewController.h"
#interface TableViewController ()
#end
#implementation TableViewController
#synthesize initialCities, filteredCities, isFiltered, searchBar;
- (void)loadView
{
[super loadView];
searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, self.tableView.frame.size.width, 44.0)];
searchBar.delegate = self;
searchBar.autoresizingMask = (UIViewAutoresizingFlexibleWidth);
searchBar.autocorrectionType = UITextAutocorrectionTypeNo;
self.tableView.tableHeaderView = searchBar;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.tableView.delegate = self;
initialCities = [[NSMutableArray alloc] initWithObjects:#"London", #"New York", #"Berlin", nil];
}
#pragma mark - UITableView DataSource Methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (isFiltered == YES)
{
return filteredCities.count;
}
else
{
return initialCities.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];
}
if (isFiltered == YES)
{
cell.textLabel.text = [filteredCities objectAtIndex:indexPath.row];
}
else
{
cell.textLabel.text = [initialCities objectAtIndex:indexPath.row];
}
return cell;
}
#pragma mark - UITableView Delegate Methods
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
}
#pragma mark - UISearchBar Delegate methods
- (void)searchBar:(UISearchBar *)searchBar TextDidBeginEditing:(NSString *)searchText
{
searchBar.showsCancelButton = YES;
if (searchText.length == 0)
{
isFiltered = NO;
}
else
{
isFiltered = YES;
filteredCities = [[NSMutableArray alloc] init];
for (NSString *cityName in initialCities)
{
NSRange cityNameRange = [cityName rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (cityNameRange.location != NSNotFound)
{
[filteredCities addObject:cityName];
}
}
}
[self.tableView reloadData];
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
[searchBar resignFirstResponder];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
The result is that the search bar is displayed, the table view is displayed, but when I type text into the search bar the table view is not filtered. There is no crash. Any help is appreciated. Thank you.
Try this
-(void)searchBar:(UISearchBar*)searchBar textDidChange:(NSString*)searchText
{
// Your filter code
}
The method you implemented is not even present in Protocol
– searchBar:textDidChange:
– searchBar:shouldChangeTextInRange:replacementText:
– searchBarShouldBeginEditing:
– searchBarTextDidBeginEditing:
– searchBarShouldEndEditing:
– searchBarTextDidEndEditing:
(void)searchBar:(UISearchBar *)searchBar TextDidBeginEditing:(NSString *)searchText
This method is not existed in searchBar's delegate.
Use searchBarTextDidBeginEditing.
Go through this tutorial. well explained.
http://www.appcoda.com/search-bar-tutorial-ios7/
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:#"name contains[c] %#", searchText];
searchResults = [actualData filteredArrayUsingPredicate:resultPredicate];
}
Related
I want to add uisearchbar in table view controller, but I search the uisearchbar tutorial in iOS 9 and try it. I can’t show the uisearchbar on the simulator of my project. It also has not the search function. If I pass the code “self.tableView.contentOffset = CGPointMake(0, CGRectGetHeight(self.searchController.searchBar.frame));”, the Xcode will show the error message. This message is “libc++abi.dylib: terminating with uncaught exception of type NSException”.
Could tell me where is wrong?
Platform: iPhone in iOS 10.3 and iPad in iOS 10.3
Xcode version:8.3.3 (8E3004b)
.h file
#import <UIKit/UIKit.h>
#interface SearchBarTableViewController : UITableViewController <UISearchControllerDelegate, UISearchBarDelegate, UISearchResultsUpdating>
#property (nonatomic, strong) UISearchController *searchController;
#property (weak, nonatomic) IBOutlet UISearchBar *searchBar;
#property(nonatomic,strong) NSMutableArray *RowArray;
#end
.m files
#pragma mark Search bar Part
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
if (!_searchController.searchBar.superview) {
self.tableView.tableHeaderView = self.searchController.searchBar;
}
if (!self.searchController.active && self.searchController.searchBar.text.length == 0) {
self.tableView.contentOffset = CGPointMake(0, CGRectGetHeight(self.searchController.searchBar.frame));
}
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
if (self.searchController.isActive) {
self.searchController.active = NO;
}
}
#pragma mark - Getters / Setters
- (UISearchController *)searchController {
if (!_searchController) {
_searchController = [[UISearchController alloc]initWithSearchResultsController:nil];
_searchController.searchResultsUpdater = self;
_searchController.dimsBackgroundDuringPresentation = NO;
_searchController.searchBar.delegate = self;
[_searchController.searchBar sizeToFit];
}
return _searchController;
}
- (NSArray *)searchResults {
NSString *searchString = self.searchController.searchBar.text;
if (searchString.length > 0) {
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF CONTAINS[c] %#", searchString];
return [self.RowArray filteredArrayUsingPredicate:predicate];
}
else {
return self.RowArray;
}
return #[];
}
#pragma mark - UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (self.searchController.isActive && self.searchController.searchBar.text.length > 0) {
return self.searchResults.count;
}
else {
return self.RowArray.count;
}
return 0;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell;
NSString *cityName = #"";
cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
if (self.searchController.isActive && (![self.searchController.searchBar.text isEqualToString:#""])) {
cityName = [self.searchResults objectAtIndex:indexPath.row];
}
else {
cityName = [self.RowArray objectAtIndex:indexPath.row];
}
cell.textLabel.text = cityName;
return cell;
}
Interface image 1 about outlet setting.
UISearchbar outlet setting.
Search Display Controller outlet setting.
I have found out the answer.
I neglect the updateSearchResultsForSearchController code.
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController {
[self.tableView reloadData];
}
My Question is this. Why is the filtered table view showing rooms, after I start typing in the search bar that are not present when printing the filtered array to the console. I thought it might be that the table view cells are being reused so set the cell label text to nil to ensure the text gets reset in tableviewcellforindex: method , all to no avail. Can anyone help?
This is my Table View Controller that acts as the data source and delegate for for both my standard tableview and filtered tableview
#import <UIKit/UIKit.h>
#import "Rooms.h"
#interface RoomsTableViewController : UITableViewController
<UISearchControllerDelegate,UISearchResultsUpdating,UISearchBarDelegate,UITableViewDelegate>
#property (strong,nonatomic) NSMutableArray *roomList;
#property (strong,nonatomic) NSMutableArray *orderedRoomList;
#property (strong,nonatomic) NSMutableArray *filteredRooms;
#property (strong,nonatomic) UITableViewController *searchResultsController;
#property (strong,nonatomic) UISearchController *searchController;
#end
#import "RoomsTableViewController.h"
#interface RoomsTableViewController ()
#property BOOL searchControllerWasActive;
#property BOOL searchControllerSearchFieldWasFirstResponder;
#end
The implementation file
#implementation RoomsTableViewController
- (void)viewDidLoad {
[super viewDidLoad];
//sort the room list into filetred by alpha numeric A10 before C1 example this will eventually be done on the server
NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:#"name" ascending:YES comparator:^NSComparisonResult(id obj1, id obj2) {
return [(NSString *)obj1 compare:(NSString *)obj2 options:NSNumericSearch];
}];
self.orderedRoomList = (NSMutableArray*)[self.roomList sortedArrayUsingDescriptors:[NSArray arrayWithObject:sort]];
self.searchResultsController= [[UITableViewController alloc]initWithStyle:UITableViewStylePlain];
self.searchController = [[UISearchController alloc]initWithSearchResultsController:self.searchResultsController];
self.searchController.searchResultsUpdater=self;
[self.searchController.searchBar sizeToFit];
self.tableView.tableHeaderView=self.searchController.searchBar;
//set up the data source and delegate of this new table view to be this (roomsTableviewcontroller) view controller
self.searchResultsController.tableView.delegate=self;
self.searchResultsController.tableView.dataSource=self;
self.searchController.delegate=self;
self.searchController.dimsBackgroundDuringPresentation=NO;
self.searchController.searchBar.delegate=self;
self.definesPresentationContext=YES;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
//restore the search controllers active state
if (self.searchControllerWasActive) {
self.searchController.active = self.searchControllerWasActive;
_searchControllerWasActive=NO;
if (self.searchControllerSearchFieldWasFirstResponder) {
[self.searchController.searchBar becomeFirstResponder];
_searchControllerSearchFieldWasFirstResponder=NO;
}
}
}
-(void)searchBarBookmarkButtonClicked:(UISearchBar *)searchBar
{
[searchBar resignFirstResponder];
}
#pragma mark - UISearchControllerDelegate
- (void)willPresentSearchController:(UISearchController *)searchController {
// do something before the search controller is presented
self.navigationController.navigationBar.translucent = YES;
}
-(void)willDismissSearchController:(UISearchController *)searchController
{
self.navigationController.navigationBar.translucent = NO;
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (tableView==self.tableView) {
return [self.orderedRoomList count];
}else{
return [self.filteredRooms count];
}
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 71;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellReuseIdentifier = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellReuseIdentifier];
if (cell==nil) {
cell= [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellReuseIdentifier];
}
Rooms *room = (tableView==self.tableView)? [self.orderedRoomList objectAtIndex:indexPath.row]: [self.filteredRooms objectAtIndex:indexPath.row];
cell.textLabel.text=nil;
NSString *labelString = [NSString stringWithFormat:#"%# %#",room.name,room.roomDescription];
cell.textLabel.text=labelString;
return cell;
}
Below is a photo of the table view in the simulator and a screen print of the check to see if the filtered array has indeed worked correctly as it has. You can see that C3 is not listed as being part of the filtered array but it still appears on screen.
data values i have one text filed and two buttons.One button is save,second button is show.
when click save button data will be Stored in Core-Data and then i click Show button data will be displayed on Console. It gone nice.
But now i want when Click show button data will be displayed on UITableView So Please Give me any idea
Thanks in advanced,
this is my code:-
#import "SetViewController.h"
#import "AppDelegate.h"
#interface SetViewController ()
{
NSMutableArray *array;
}
#end
#implementation SetViewController
#synthesize textField;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)save:(id)sender {
AppDelegate *appD=(AppDelegate *) [[UIApplication sharedApplication]delegate];
NSEntityDescription *entit=[NSEntityDescription insertNewObjectForEntityForName:#"Team" inManagedObjectContext:appD.managedObjectContext];
[entit setValue:textField.text forKey:#"fname"];
NSError *error;
BOOL isSaved=[appD.managedObjectContext save:&error];
NSLog(#"succesfully saved flag: %d",isSaved);
}
- (IBAction)show:(id)sender {
AppDelegate *appDelegat=(AppDelegate*)[[UIApplication sharedApplication]delegate];
NSEntityDescription *entity=[NSEntityDescription entityForName:#"Team" inManagedObjectContext:appDelegat.managedObjectContext];
NSFetchRequest *fetchRr = [[NSFetchRequest alloc]init];
[fetchRr setEntity:entity];
array=[[appDelegat.managedObjectContext executeFetchRequest:fetchRr error:nil]mutableCopy];
NSLog(#"array %#",array);
for (NSManagedObject *obj in array) {
NSLog(#"Name :%#\n",[obj valueForKey:#"fname"]);
}
}
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
#end
i am tried like this :-
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"ShowData"])
{
ShowViewController *destViewController = segue.destinationViewController;
destViewController.second = [[array valueForKey:#"fname"] componentsJoinedByString(angry)" , "];
NSLog(#" got data for array %#",destViewController.second);
}
}
ShowViewController.h:-
#import <UIKit/UIKit.h>
#import "SetViewController.h"
#interface ShowViewController : UITableViewController<UITableViewDelegate,UITableViewDataSource>
#property (nonatomic, strong) NSString *second;
#end
ShowViewController.m:-
import "ShowViewController.h"
#interface ShowViewController ()
{
NSMutableArray *acess;
}
#end
#implementation ShowViewController
#synthesize second;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
acess =[second componentsSeparatedByString:#", "];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [acess count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] ;
}
cell.textLabel.text = [acess objectAtIndex:indexPath.row];
return cell;
}
ShowViewController is UITableView.When Click UItableView is open but data will be not Displayed So Please give me any idea
Follow following steps and also read programming guide of UITableview provided by apple:
After getting the array just reload your table view.
Make number of rows = array count.
Customize the cell as per your need.
If you only declared the array as per you shown in code then you must need to initialise it in view did load like this:
array=[NSMutablearray array];
after that get the values from db and stored in array an use UITable view delegate and datasource methods.
First declare your array in your viewDidload() method.
- (void)viewDidLoad
{
yourArray=[[NSArray alloc]initWithObjects:Obj1,obj2,obj3,obj4,obj5, nil];
}
and then use tableview delegate methods. to set array data to tableview.
- (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 [yourArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
// Configure the cell...
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Cell"];
}
cell.textLabel.text=[yourArray objectAtIndex:indexPath.row];
return cell;
}
If you already have an NSArray that contains your strings, there is no need to go through the whole componentsJoinedByString/componentsSeparatedByString - you can just pass the array to your second view controller.
Accessing the passed data in viewDidLoad won't work though because when you set the property in prepareForSegue the view has already loaded.
Your prepareForSegue should be -
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"ShowData"])
{
ShowViewController *destViewController = (ShowViewController *)segue.destinationViewController;
destViewController.fnames = [array valueForKey:#"fname"];
}
}
In your .h file for ShowViewController declare a property to receive frames -
#property (strong,nonatomic) NSArray *fnames;
Then your table data source methods will be -
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.fnames 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] ;
}
cell.textLabel.text = [self.fnames objectAtIndex:indexPath.row];
return cell;
}
I am trying to gain some knowledge on UISearchDisplayController and going through some tutorial with examples, I have the below class ready with a search bar and table view with data on it.
Header file:
#import <UIKit/UIKit.h>
#interface MyClass : UIViewController <UITableViewDataSource, UITableViewDelegate, UISearchDisplayDelegate, UISearchBarDelegate>
#property (nonatomic, strong) IBOutlet UITableView *suggestionsTableView;
#property (nonatomic, strong) IBOutlet UISearchBar *searchBar;
#end
Implementation file:
#import "MyClass.h"
#interface DVWNoteTypeSuggestionDisplayController ()
#property (nonatomic, strong) NSArray *items;
#property (nonatomic)BOOL isSearching;
#property (nonatomic, strong) NSMutableArray *filteredList;
#end
#implementation MyClass
- (id)init
{
self = [super initWithNibName:#"SuggestionDisplayController" bundle:BUNDLE];
if (self)
{
// Set the title.
self.title = #"test";
}
return self;
}
- (void)viewDidLoad
{
self.searchBar = [[UISearchBar alloc] init];
[[UISearchDisplayController alloc] initWithSearchBar:self.searchBar contentsController:self];
self.searchDisplayController.searchResultsDelegate = self;
self.searchDisplayController.searchResultsDataSource = self;
self.searchDisplayController.delegate = self;
self.searchBar.frame = CGRectMake(0, 0, 0, 38);
self.suggestionsTableView.tableHeaderView = self.searchBar;
self.items = [[NSArray alloc] initWithObjects:#"Item No. 1", #"Item No. 2", #"Item No. 3", #"Item No. 4", #"Item No. 5", #"Item No. 6", nil];
self.isSearching = NO;
self.filteredList = [[NSMutableArray alloc] init];
}
#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.
// // Usually the number of items in your array (the one that holds your list)
// return [self.items count];
//}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
if (self.isSearching)
{
//If the user is searching, use the list in our filteredList array.
return [self.filteredList count];
} else
{
return [self.items count];
}
}
//- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
// //Where we configure the cell in each row
//
// static NSString *CellIdentifier = #"Cell";
// UITableViewCell *cell;
//
// cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// if (cell == nil) {
// cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
// }
// // Configure the cell... setting the text of our cell's label
// cell.textLabel.text = [self.items objectAtIndex:indexPath.row];
// return cell;
//}
- (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];
}
// Configure the cell...
NSString *title;
if (self.isSearching && [self.filteredList count]) {
//If the user is searching, use the list in our filteredList array.
title = [self.filteredList objectAtIndex:indexPath.row];
} else
{
title = [self.items objectAtIndex:indexPath.row];
}
cell.textLabel.text = title;
return cell;
}
- (void)filterListForSearchText:(NSString *)searchText
{
[self.filteredList removeAllObjects]; //clears the array from all the string objects it might contain from the previous searches
for (NSString *title in self.items) {
NSRange nameRange = [title rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (nameRange.location != NSNotFound) {
[self.filteredList addObject:title];
}
}
}
#pragma mark - UISearchDisplayControllerDelegate
- (void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller {
//When the user taps the search bar, this means that the controller will begin searching.
self.isSearching = YES;
}
- (void)searchDisplayControllerWillEndSearch:(UISearchDisplayController *)controller {
//When the user taps the Cancel Button, or anywhere aside from the view.
self.isSearching = NO;
}
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
[self filterListForSearchText:searchString]; // The method we made in step 7
// Return YES to cause the search result table view to be reloaded.
return YES;
}
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption
{
[self filterListForSearchText:[self.searchDisplayController.searchBar text]]; // The method we made in step 7
// Return YES to cause the search result table view to be reloaded.
return YES;
}
#end
Whenever I try to search for any items in the data set (eg: "Item No. 5") its not hitting the breakpoints on any of the delegate i.e. actually the search is not working. Please suggest what am I missing here as this is just my learning project right now.
It appears that a UISearchDisplayController created programatically in this way is prematurely zeroing the delegate, even though the view controller is retaining the UISearchDisplayController as expected.
Add the following to the end of your viewDidLoad and you'll see that the first log will be a valid object, but the second will be null.
NSLog(#"Delegate should be %#", self.searchDisplayController.delegate);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(#"Delegate is %#", self.searchDisplayController.delegate);
});
The quickest way I've found to get around this is to store your own reference to the UISearchDisplayController via a private property or ivar.
If you have to create object for search bar controller and set delegate search bar its work.
UISearchBar *searchBar = [[UISearchBar alloc] init];
[[UISearchDisplayController alloc] initWithSearchBar:searchBar contentsController:self];
self.searchDisplayController.searchResultsDelegate = self;
self.searchDisplayController.searchResultsDataSource = self;
self.searchDisplayController.delegate = self;
searchBar.frame = CGRectMake(0, 0, 0, 38);
self.tableView.tableHeaderView = searchBar;
I am trying to link from a dynamic table view cell (as part of a search result table) to a specific view controller
The code I have implemented so far is:
SearchViewController.h
import <UIKit/UIKit.h>
#interface SearchViewController : UITableViewController <UISearchDisplayDelegate, UISearchDisplayDelegate>
#property (strong,nonatomic) NSArray *sysTArray;
#property (strong,nonatomic) NSMutableArray *filteredsysTArry;
#property IBOutlet UISearchBar *sysTSearchBar;
#end
SearchViewController.M
#import "SearchViewController.h"
#import "sysT.h"
#interface SearchViewController ()
#end
#implementation SearchViewController
#synthesize sysTArray;
#synthesize filteredsysTArry;
#synthesize sysTSearchBar;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
sysTArray = [NSArray arrayWithObjects:
[sysT sysTOfCategory:#"p" name:#"H1"],
[sysT sysTOfCategory:#"p" name:#"W2"],
[sysT sysTOfCategory:#"p" name:#"W3"],
[sysT sysTtOfCategory:#"p" name:#"C4"],
[sysT sysTOfCategory:#"c" name:#"O5"],
[sysT sysTOfCategory:#"c" name:#"C6"],
[sysT sysTOfCategory:#"a" name:#"L7"], nil];
self.filteredSysTArry = [NSMutableArray arrayWithCapacity:[sysTArray count]];
[self.tableView reloadData];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (tableView == self.searchDisplayController.searchResultsTableView) {
return [filteredsysTArry count];
}else{
return [sysTArray count];
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
- (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];
}
SysT *sysT = nil;
if (tableView == self.searchDisplayController.searchResultsTableView) {
sysT = [filteredsysTArry objectAtIndex:indexPath.row];
}else{
sysT = [sysTArray objectAtIndex:indexPath.row];
}
cell.textLabel.text = sysT.name;
[cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
return cell;
}
#pragma mark Search Filtering
-(void)filterContentForSearchText:(NSString*) searchText scope:(NSString*)scope {
[self.filteredSysTArry removeAllObjects];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF.name contains[c] %#", searchText];
filteredSysTArry = [NSMutableArray arrayWithArray:[sysTArray filteredArrayUsingPredicate:predicate]];
}
#pragma mark - UISearchDisplayController Delegate Methods
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
[self filterContentForSearchText:searchString scope:
[[self.searchDisplayController.searchBar scopeButtonTitles] objectAtIndex: [self.searchDisplayController.searchBar selectedScopeButtonIndex]]];
return YES;
}
-(BOOL) searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption {
[self filterContentForSearchText:self.searchDisplayController.searchBar.text scope:
[[self.searchDisplayController.searchBar scopeButtonTitles] objectAtIndex:searchOption]];
return YES;}
#end
How do I initiate a specific view controller depending on the data inside the dynamic cell?
To further elaborate, if a user searched H1, and then clicked on that dynamic cell, how would I display the relevant H1 view controller?
As you can probably tell from my very rough code, I'm on a steep learning curve. If you could make your answers as baby proof as possible that would be fantastic, and would really help me out. (Also, I am using storyboards).
Thanks!
You need to implement tableView:didSelectRowAtIndexPath: which is called when you select a row. You can get the data for that row by querying your data source, using the indexPath passed into that method. You can then use whatever logic you need to choose which view controller to go to next. You do that by calling performSegueWithIdentifier.