I am building an iPhone application loading data from SQLite database. Until now I have managed to deal with it as it should, but now i need to add a search bar on top to search through the database content dynamically and obtain the proper search results.
I am using Xcode 4.3.3 , and I am a newb in Xcoding.
I have seen almost every tutorial ever posted online and i need some help.
Anyone have any very specific tutorial or sample code that could help? It will be highly appreciated.
Everyone this is the most helpful link ever found
http://code-ninja.org/blog/2012/01/08/ios-quick-tip-filtering-a-uitableview-with-a-search-bar/
You could use an NSPredicate.
http://developer.apple.com/library/ios/#DOCUMENTATION/Cocoa/Reference/Foundation/Classes/NSPredicate_Class/Reference/NSPredicate.html
[NSPredicate predicateWithFormat:#"whatYouAreSearching LIKE %#", searchBar.text];
If you're using an NSFetchRequest, you can assign it a predicate using it's setPredicate method.
Your controller must implement UISearchBarDelegate protocol
then in init method, add this or similar
CGRect searchBarRect = CGRectMake(0, 0, self.view.bounds.size.width, 44);
_searchBar = [[UISearchBar alloc] initWithFrame:searchBarRect];
_searchBar.delegate = self;
after that, implement these three methods, I will post something that looks like mine implementations
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar {
[searchBar setShowsCancelButton:YES animated:YES];
self.tableView.allowsSelection = NO;
self.tableView.scrollEnabled = NO;
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
searchBar.text=#"";
[searchBar setShowsCancelButton:NO animated:YES];
[searchBar resignFirstResponder];
self.tableView.allowsSelection = YES;
self.tableView.scrollEnabled = YES;
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
[searchBar setShowsCancelButton:NO animated:YES];
[searchBar resignFirstResponder];
self.tableView.allowsSelection = YES;
self.tableView.scrollEnabled = YES;
/* fire method that does querying with searchBar.text as attribute */
[self some method:searchBar.text];
}
Related
In the options the paste and define was OK , but when i click the copy or cut it will crash. I tried to deleted all code except about the search bar , but it did not work on too.and I tried to override the textfield method but the search bar subviews did not contain a UITextField
this is my code
_searchBar = [[UISearchBar alloc] initWithFrame:self.topBar.bounds];
[_searchBar setPlaceholder:LS(#"Search", #"")];
[_searchBar setDelegate:self];
_searchController = [[UISearchDisplayController alloc] initWithSearchBar:_searchBar contentsController:self];
_searchController.delegate = self;
_searchController.searchResultsDataSource = self;
_searchController.searchResultsDelegate = self;
if( _scopeButtonTitles ) {
_searchBar.scopeButtonTitles = _scopeButtonTitles;
_searchBar.showsScopeBar = YES;
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[_searchBar resignFirstResponder];
}
#pragma mark - UISearchBarDelegate
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
_searchResultsAvailable = NO;
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
self.loadingTitle = [NSString stringWithFormat:#"%# %#%#",LS(#"Searching", #""),self.title?self.title:#"",#"..."];
_searchResultsAvailable = YES;
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
_searchResultsAvailable = NO;
}
I had debuted the bug many times, and found the error in my app.
It just need to rewrite the copy and cut method for the searchBar.
After I rewrite the methods the bug had gone
I have a view controller which is fully occupied by a UINavigationBar and UITableView. When the user taps the search bar in the UITableView, I want to hide the navigation bar and allow the table view to fully occupy the screen. Here's my code:
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
NSLog(#"typing text");
navBar.hidden = YES;
[tableview setFrame:CGRectMake(0, 20, 320, 568)];
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
NSLog(#"clearing text");
navBar.hidden = NO;
[tableview setFrame:CGRectMake(0, 64, 320, 504)];
}
However, the appearance/frame change code is not working. On the other hand, I know these methods are being called because the NSLogs show up. Can anyone offer any solution?
Try this instead:
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
NSLog(#"typing text");
[self.navigationController setNavigationBarHidden:YES animated:YES];
[self.tableView setFrame:CGRectMake(0, 20, 320, 568)];
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
NSLog(#"clearing text");
[self.navigationController setNavigationBarHidden:NO animated:YES];
[self.tableView setFrame:CGRectMake(0, 64, 320, 504)];
}
There is something about adding the animation flag that corrects the problem. Hope this helps!
You should use search display controller (UISearchDisplayController class) for the search functionality.
A search display controller manages display of a search bar and a table view that displays the results of a search of data. I believe it also comes with the functionality you are attempting to create above.
This guide is helpful: http://www.appcoda.com/search-bar-tutorial-ios7/
I implemented a search bar and search display controller on top of my table view.
When the view loads the search bar and relative scopes are always visible.
Is there a simple way to hide it until the user scrolls down, like it happens in the Music app?
You need to add search bar as a header of the table view and then set the contentoffset property of table view in viewDidLoad as,
[self.tableView setContentOffset:CGPointMake(0,44) animated:YES];//or (0, 88) depends on the height of it
For search display controller, you can try this as well,
[self.searchDisplayController setActive:NO animated:YES];
another approach without hardcode
[self.tableView setContentOffset:CGPointMake(0.0, self.tableView.tableHeaderView.frame.size.height) animated:YES];
After a few hours of hair pulling, something that works
on iOS 9
doesn't depend on the number of rows in the table
with variable height rows
Considering the searchbar is the tableView.tableHeaderView
#interface MyTableViewController ()
#property (nonatomic, assign) BOOL firstLayout;
#end
- (void) viewDidLoad {
[super viewDidLoad];
self.firstLayout = YES;
//your code
}
-(void)viewDidLayoutSubviews{
[super viewDidLayoutSubviews];
if(self.firstLayout){
CGPoint offset = CGPointMake(0, self.tableView.tableHeaderView.frame.size.height - self.tableView.contentInset.top);
[self.tableView setContentOffset:offset];
self.firstLayout = NO;
}
}
for iOS 7 and using UINavigationController
[self.tableView setContentOffset:CGPointMake(0, self.searchBar.height + self.navigationController.navigationBar.height)];
Best way i did reload tableview in
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:YES];
[self performSelector:#selector(reload:) withObject:nil afterDelay:0.0];
self.edgesForExtendedLayout = UIRectEdgeNone;
}
- (void)reload:(__unused id)sender {
[self.searchDisplayController setActive:YES];
[self.tableView reloadData];
[self.refreshControl endRefreshing];
} else {
[self.refreshControl endRefreshing];
[[[UIAlertView alloc]initWithTitle:#"Error" message:[error localizedDescription] delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil] show];
}
}
Thanks
This works fine on iOS9+
- (void)viewDidLoad {
[super viewDidLoad];
dispatch_async(dispatch_get_main_queue(), ^{
self.tableView.contentOffset = CGPointMake(0, -20);
});
}
i´m having a tough time with UISearchDisplayController. In my scenario i have an UIView pushed onto a navgation controller. In the UIView i have an UITableView and UIToolbar. In the UITableView I´m using UISearchDisplayController.
The toolbar buttons are used to add additional filter options to the search. My problem is that I can´t figure out, how to add the toolbar at the bottom of the result table view of the UISearchDisplayController.
What is the way to go to add a toolbar to the results?
I finally managed to solve my problem.
Instead of using UISearchDisplayController i only add a UISearchBar to my UITableView and replicate the behavior of UISearchDisplayController with the UISearchBarDelegate methods.
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
[self setSearchText:searchText];
[self filterCards];
}
- (void)searchBar:(UISearchBar *)searchBar selectedScopeButtonIndexDidChange:(NSInteger)selectedScope
{
[self setScopeIndex:selectedScope];
[self filterCards];
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
// Move searchbar to table view
[self.chapterSearchBar removeFromSuperview];
[self.chapterTableView addSubview:[self chapterSearchBar]];
// Show navigation controller
[self.navigationController setNavigationBarHidden:NO animated:YES];
// Hide scope bar an resize
[searchBar setShowsScopeBar:NO];
[searchBar sizeToFit];
// Hide cancel button
[searchBar setShowsCancelButton:NO animated:YES];
// Resize table view
CGRect tableViewRect = [self.chapterTableView frame];
tableViewRect.origin.y = 0;
[self.chapterTableView setFrame:tableViewRect];
// Hide keyboard
[searchBar resignFirstResponder];
[self setSearchText:#""];
[self filterCards];
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
[searchBar resignFirstResponder];
}
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar
{
// Move searchbar to controller view
[self.chapterSearchBar removeFromSuperview];
[self.view addSubview:[self chapterSearchBar]];
// Hide navigation controller
[self.navigationController setNavigationBarHidden:YES animated:YES];
// Show scope bar an resize
[searchBar setShowsScopeBar:YES];
[searchBar sizeToFit];
// Show cancel button
[searchBar setShowsCancelButton:YES animated:YES];
// Resize table view
CGRect tableViewRect = [self.chapterTableView frame];
tableViewRect.origin.y = 44;
[self.chapterTableView setFrame:tableViewRect];
return YES;
}
If anyone's curious how to solve this issue with still using UISearchDisplayController (cleaner probably), simply set the items of your toolbar to your view controller's toolbarItems while search is active:
self.navigationController.toolbarHidden = NO;
self.toolbarItems = optionsToolbar.items;
The UISearchDisplayController retains the view controller's toolbar according to toolbarItems, so this might already be done for you. Can be useful if the toolbar is only being used during search.
I created a search bar programmatically and added to my view using the codes below:
- (void)viewDidLoad
{
searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(xPositionForSearchBar, yPositionForSearchBar, widthForSearchBar, heightForSearchBar)];
UIView *bg = [[searchBar subviews] objectAtIndex:0];
searchBar.delegate = self;
searchBar.placeholder = #"Search record";
for(UIView *view in searchBar.subviews){
if([view isKindOfClass:[UITextField class]]){
UITextField *tf = (UITextField *)view;
tf.delegate = self;
break;
}
}
[bg removeFromSuperview];
[self.view addSubview: searchBar];
}
The code is implemented with UISearchBarDelegate and UITextFieldDelegate.
I have tried using
- (void)searchBarCancelButtonClicked:(UISearchBar *)aSearchBar
{
NSLog(#"cancel clicked");
searchBar.text = #"";
[aSearchBar resignFirstResponder];
}
- (BOOL)textFieldShouldClear:(UITextField *)textField
{
NSLog(#"clear");
[self performSelector:#selector(searchBarCancelButtonClicked:) withObject:searchBar afterDelay: 0.1];
return YES;
}
and yet, the text inside the searchBar is not cleared at all when i click on the "clear button" - a circle with a "X" inside.
The clear button works when I implemented it in IB. Wonder why?
Kindly advice, many thanks.
This might happen if you position your search bar out of the bounds of a parent view. Then, the touches aren't delivered to your searchBar properly. This also affects text editing controls like copy & paste.
I have checked your code it work fine on device as well as on simulator.