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.
Related
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/
In my iOS app, I would like to have a right side search button in my UINavigationController, and when a user touches the button, the UISearchBar above my UITableView is shown.
I would like the UISearchBar hidden when the view loads, and then hidden again when the user clicks the Cancel button in the UISearchDisplayController.
I've searched everywhere and cannot find an example. Help?
There is a nice sample project here. The key points are:
1.Hide the Search Bar before presenting the View:
-(void)viewWillAppear:(BOOL)animated {
[self hideSearchBar];
}
-(void)hideSearchBar {
CGRect newBounds = self.tableView.bounds;
newBounds.origin.y = newBounds.origin.y + self.searchBar.bounds.size.height;
self.tableView.bounds = newBounds;
}
2.On the action target for your search button, display the Search Bar
// make the search bar visible
// code example from https://github.com/versluis/Table-Seach-2013 to deal with iOS 7 behavior
-(IBAction)displaySearchBar:(id)sender {
[self.tableView scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:YES];
NSTimeInterval delay;
if (self.tableView.contentOffset.y >1000) delay = 0.4;
else delay = 0.1;
[self performSelector:#selector(activateSearch) withObject:nil afterDelay:delay];
}
- (void)activateSearch
{
[self.tableView scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:NO];
[self.searchBar becomeFirstResponder];
}
3.Finally, hide the SearchBar when Cancel is clicked
-(void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
[self hideSearchBar];
}
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 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.
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];
}