I am making something like facebook app's left panel search feature. I have two UITableViewControllers. I take a tableView from one of them and put it above another one, when user taps on UISearchBar to show search results. When I create this second UITableViewController, I tell, that it's separator style will be none in ViewDidLoad method:
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
And then, after I put it's tableView above the first UITableViewController's view, it is empty at first, since no data is yet entered to the UISearchBar. And there are no any separators. But then, when user enters any letter and table data has some records, the separator style returns to the default one (white lines).
So, for some reason, my second controller forgets, what should be the separator style and displays after the reload of table view separators again. What can be the reason?
Edit:
This is how I create my second UITableViewController and take it's tableView to put on the first controller's view:
- (UIView *)searchResultsView
{
if (! _searchResultsView) {
_searchResultsView = self.searchResultsViewController.tableView;
_searchResultsView.frame = CGRectMake(0, 44, 320, self.view.frame.size.height-44);
}
return _searchResultsView;
}
- (SearchResultsViewController *)searchResultsViewController
{
if (! _searchResultsViewController) {
_searchResultsViewController = [[SearchResultsViewController alloc] init];
_searchResultsViewController.searchBar = _searchBar;
}
return _searchResultsViewController;
}
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
[self.view addSubview:self.searchResultsView];
}
Screenshot:
This is how it looks, when there is no data for table view:
As you see, there are no separators.
This is how it looks, when there is data. I have deleted cell contents. As you see, there are white separators.
The problem was that I used UISearchController and it creates it's own tableView. So I had even 3 tableViews there. After I removed UISearchController and it's delegate methods, everything started working. Now I take a string from UISearchBar and transfer it to my second UITableViewController. UISearchController is not needed there.
- (BOOL)searchBar:(UISearchBar *)searchBar shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
NSString *searchString = [_searchBar.text stringByReplacingCharactersInRange:range withString:text];
self.searchResultsViewController.searchString = searchString;
return YES;
}
And I use custom setter for searchString in second UITableViewController:
- (void)setSearchString:(NSString *)searchString
{
_searchString = searchString;
[self filterContentForSearchText:searchString];
[self.tableView reloadData];
}
Try with self.tableView.separatorColor = [UIColor clearColor];
I need a help . Actually when I tap or click on search button then I should get a black screen . As you could see using in ABPeoplePicker.So it is possible with UITableView ? I've added an image that can help you in getting my question.
here is my code :-
-(void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
if(searching)
return;
[searchBar setShowsCancelButton:YES animated:YES];
searching = YES;
letUserSelectRow = NO;
[contactTableView setScrollEnabled:NO];
}
![Example image][1]
If you add a UISearchDisplayController instead of a UISearchBar, the black screen will come automatically. If you need it in some other places than UISearchBar, you have to add view with black background color and show/hide it when needed.
Is there a possibility to reset a UISearchbar with searchDisplayController programmatically which is active and already contains text?
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (tableView == self.searchDisplayController.searchResultsTableView) {
searchDisplayController.searchResultsTableView.hidden = YES;
searchBar.showsCancelButton = NO;
[searchBar resignFirstResponder];
}
}
This solution is working, but there is still text in the searchBar. If i add those lines of code:
searchBar.text = #"";
There is always a black transparent view left.
Any solutions?
Here ya go. This is a delegate method called when the user hits cancel. If you want to wire it up differently just declare your search bar as an outlet and reference it. Anyway:
-(void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
searchBar.text = #"";
[searchBar resignFirstResponder];
}
Pretty sure what you're looking for is UISearchDisplayController.active
From the SDK:
#property(nonatomic, getter=isActive) BOOL active
If you set this value directly, any change is performed without animation. Use setActive:animated: if a change in state should be animated.
When the user focus in the search field of a managed search bar, the search display controller automatically displays the search interface. You can use this property to force the search interface to appear.
This thread is so old it has dust. Still here we are in swift so
<#your UISearchController variable#>.isActive = false
don't you have to retire the firstResponder
[self.searchBar resignFirstResponder]
You can also explicitly hide the resultsTableView, if that's what you want:
searchDC.searchResultsTableView.hidden=YES;
(searchDC is an instance of UISearchDisplayController)
This will help you with hiding the Cancel button and stuff: http://www.alexandre-gomes.com/?p=418
I want to have a simple SearchBar in ObjectiveC. Using UISearchBar or UISearchBarDelegate is confusing me. I could have used a UITextField but it does not have the look & feel of a search bar.
As in the image attached, I want just the searchbar no UITableView associated with it. The image has a TableView attached but you get the point. Also after someone enters text into the searchBar & pressed "enter" how do I retrieve the text?
UPDATE: I am aware of these links which discuss the same, but they are more in light with using tables.
http://blog.webscale.co.in/?p=228
http://ved-dimensions.blogspot.com/2009/02/iphone-development-adding-search-bar-in.html
How to implement search bar in iPhone?
UISearchBar Sample Code
UISearchBar in UITableViewController?
Just make your view controller implement the UISearchBarDelegate. In your xib file, all you need to do is to add a UISearchBar to your view and configure it as necessary, create an outlet for it (optional really but helps to be explicit), and assign the delegate outlet to your view controller.
Then, to respond to the search bar events, implement the UISearchBarDelegate protocol methods as necessary. For example:
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
[self handleSearch:searchBar];
}
- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar {
[self handleSearch:searchBar];
}
- (void)handleSearch:(UISearchBar *)searchBar {
NSLog(#"User searched for %#", searchBar.text);
[searchBar resignFirstResponder]; // if you want the keyboard to go away
}
- (void)searchBarCancelButtonClicked:(UISearchBar *) searchBar {
NSLog(#"User canceled search");
[searchBar resignFirstResponder]; // if you want the keyboard to go away
}
Whenever a user begins editing a UISearchDisplayController's search bar, the search controller becomes active and hides the view's navigation bar while presenting the search table view. Is it possible to prevent a UISearchDisplayController from hiding the navigation bar without reimplementing it?
I just debugged a bit into UISearchDisplayController and found that it's calling a private method on UINavigationController to hide the navigation bar. This happens in -setActive:animated:. If you subclass UISearchDisplayController and overwrite this method with the following code you can prevent the navigationBar from being hidden by faking it to be already hidden.
- (void)setActive:(BOOL)visible animated:(BOOL)animated;
{
if(self.active == visible) return;
[self.searchContentsController.navigationController setNavigationBarHidden:YES animated:NO];
[super setActive:visible animated:animated];
[self.searchContentsController.navigationController setNavigationBarHidden:NO animated:NO];
if (visible) {
[self.searchBar becomeFirstResponder];
} else {
[self.searchBar resignFirstResponder];
}
}
Let me know if this works for you. I also hope this won't break in future iOS versions... Tested on iOS 4.0 only.
The new UISearchController class introduced with iOS 8 has a property hidesNavigationBarDuringPresentation which you can set to false if you want to keep the navigation bar visible (by default it will still be hidden).
The simplest solution and no hacks.
#interface MySearchDisplayController : UISearchDisplayController
#end
#implementation MySearchDisplayController
- (void)setActive:(BOOL)visible animated:(BOOL)animated
{
[super setActive: visible animated: animated];
[self.searchContentsController.navigationController setNavigationBarHidden: NO animated: NO];
}
#end
The above answers didn't work quite right for me. My solution is to fool the UISearchDisplayController into thinking there wasn't a UINavigationController.
In your view controller, add this method
- (UINavigationController *)navigationController {
return nil;
}
This had no untoward side effects for me, despite seeming like a really bad idea... If you need to get at the navigation controller, use [super navigationController].
Since iOS 8.0 the same behavior can be achieved by setting the UISearchController's self.searchController.hidesNavigationBarDuringPresentation property to false.
The code in Swift looks like this:
searchController.hidesNavigationBarDuringPresentation = false
Tried this a different way, without subclassing UISearchDisplayController. In your UIViewController class where you set the delegate for UISearchDisplayController, implement searchDisplayControllerDidBeginSearch: and add use
[self.navigationController setNavigationBarHidden:NO animated:YES];
Did the trick for me, hope that helps.
I ran into this while tackling a slightly different problem. While using UISearchDisplayController, I want the search bar to be in the navigation bar (not under).
It's not hard to put the search bar in the navigation bar (see UISearchBar and UINavigationItem). However, UISearchDisplayController assumes the search bar is always underneath the navigation bar and (as discussed here) insists on hiding the navigation bar when entering search, so things look awful. Additionally, UISearchDisplayController tints the search bar lighter than normal.
I found a solution. The trick is to (counter-intuitively) unhook UISearchDisplayController from controlling any UISearchBar at all. If using xibs, this means deleting the search bar instance, or at least unhooking the outlet. Then create your own UISearchBar:
- (void)viewDidLoad
{
[super viewDidLoad];
UISearchBar *searchBar = [[[UISearchBar alloc] init] autorelease];
[searchBar sizeToFit]; // standard size
searchBar.delegate = self;
// Add search bar to navigation bar
self.navigationItem.titleView = searchBar;
}
You will need to manually activate the search display controller when the user taps the search bar (in -searchBarShouldBeginEditing:) and manually dismiss the search bar when the user ends searching (in -searchDisplayControllerWillEndSearch:).
#pragma mark <UISearchBarDelegate>
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar {
// Manually activate search mode
// Use animated=NO so we'll be able to immediately un-hide it again
[self.searchDisplayController setActive:YES animated:NO];
// Hand over control to UISearchDisplayController during the search
searchBar.delegate = (id <UISearchBarDelegate>)self.searchDisplayController;
return YES;
}
#pragma mark <UISearchDisplayDelegate>
- (void) searchDisplayControllerDidBeginSearch:(UISearchDisplayController
*)controller {
// Un-hide the navigation bar that UISearchDisplayController hid
[self.navigationController setNavigationBarHidden:NO animated:NO];
}
- (void) searchDisplayControllerWillEndSearch:(UISearchDisplayController
*)controller {
UISearchBar *searchBar = (UISearchBar *)self.navigationItem.titleView;
// Manually resign search mode
[searchBar resignFirstResponder];
// Take back control of the search bar
searchBar.delegate = self;
}
Really nice solution, but it was crashing my app under iOS6. I had to make the following modification to get it work.
#implementation ICSearchDisplayController
- (void)setActive:(BOOL)visible animated:(BOOL)animated
{
if (visible == YES) {
[super setActive:visible animated:animated];
[self.searchContentsController.navigationController setNavigationBarHidden:NO animated:NO];
} else {
[super setActive:NO animated:NO];
}
}
This seem to solve it for me. Tested in both iOS5/6.1. No visual issues that I could see.
- (void)viewDidAppear
{
[super viewDidAppear];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillAppear:) name:UIKeyboardWillShowNotification object:nil];
}
-(void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)keyboardWillAppear:(NSNotification *)notification
{
[self.navigationController setNavigationBarHidden:NO animated:NO];
}
-(void)viewDidLayoutSubviews{
[self.navigationController setNavigationBarHidden:NO animated:NO];
}
iOS 7 screws things up a bit... for me this worked perfectly:
/**
* Overwrite the `setActive:animated:` method to make sure the UINavigationBar
* does not get hidden and the SearchBar does not add space for the statusbar height.
*
* #param visible `YES` to display the search interface if it is not already displayed; NO to hide the search interface if it is currently displayed.
* #param animated `YES` to use animation for a change in visible state, otherwise NO.
*/
- (void)setActive:(BOOL)visible animated:(BOOL)animated
{
[[UIApplication sharedApplication] setStatusBarHidden:YES];
[self.searchContentsController.navigationController setNavigationBarHidden:YES animated:NO];
[super setActive:visible animated:animated];
[self.searchContentsController.navigationController setNavigationBarHidden:NO animated:NO];
[[UIApplication sharedApplication] setStatusBarHidden:NO];
}
The reason for show/hide the statusbar
I think the best solution is to implement the UISearchDisplayController yourself.
It's not that difficult. You only need to implement UISearchBarDelegate for your UIViewController and include a UITableView to display your search results.
#Pavel's works perfectly well. However, I was trying to get this into a UIPopoverController and the text in the field gets pushed slightly when the search bar's text field becomes the first responder, and that looks a bit ugly, so I fixed it by calling the super method with
animated set to NO.
As jrc pointed out "unhook UISearchDisplayController from controlling any UISearchBar" seems to work for me. If I pass nil as a parameter when creating UISearchDisplayController the navigation bar stays visible at all times:
searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:nil contentsController:self];
I was adding custom navigation bar on my ViewController which was getting hidden on search, a quick but not so good fix was
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText{
[self.view addSubview:_navBar];
}
_navBar is UINavigationBar added programmatically,
doing this helped me navigation bar from hiding.
Just wanted to add to stigi answer. When you cancel search and start search again - search results table won't be react to touches so you need to add next line
self.searchResultsTableView.alpha = 1;
So updated code looks next way
- (void)setActive:(BOOL)visible animated:(BOOL)animated;
{
if(self.active == visible) return;
if (visible) {
[self.searchContentsController.navigationController setNavigationBarHidden:YES animated:NO];
[super setActive:visible animated:animated];
[self.searchContentsController.navigationController setNavigationBarHidden:NO animated:NO];
self.searchResultsTableView.alpha = 1;
[self.searchBar becomeFirstResponder];
} else {
[super setActive:visible animated:animated];
[self.searchBar resignFirstResponder];
}
}