iOS - Keep ScopeBar even after Cancel Button click - ios

I set the setShowsScopeBar to TRUE from the very beginning, and that works perfectly. But once I search something and then cancel my search, the Scope Bar disappears.
How to keep scopebar even after pressed Cancel button?
Apparently, in earlier version, with the UISearchBar,
- (BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar
{
[searchBar setShowsScopeBar:YES];
return YES;
}
This worked. But with the SearchController, it isn't the case anymore.
I have tried this:
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
searchController.searchBar.showsScopeBar = YES;
[searchController.searchBar sizeToFit];
isSearching = NO;
}
with no luck.
Are there any possible solutions out there on iOS 9?

There is no direct way of keeping the scope bar always visible unless you use some hacks.
Instead use a UISegmentedControl which looks like a scope bar. Then handle the filtering of the search results in
- updateSearchResultsForSearchController: based on the selected segment.

The element is a UISegmentedControl with the UISegmentedControlStyleBar style. You can set the tintColor property to get the color desired. Just put the view above the table view and you can get something that looks like that screenshot.

Related

How to set a recent search history drop down for UISearchBar in iOS

I want to set a recent search history dropdown for UISearchbar . I have implemented a dropdown programatically using a UITableView
Logic:
How i have implemented is by setting a UITableView right below the UISearchBar and on click on the UISearchBar it will pop up .
Am initially hiding that tableview in viewdidload and in
-(BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar am unhiding the tableview .
Iam facing too many problems with this :
1. The return button is not enabled when the searchbartext is empty .In that case if i have to cancel/hide the table view again i have to depend on tapgestures .
2. Clicking on the searchbartext again won't trigger any of its delegates. The only time it triggers the delegates on click on the searchbartext is when click on it for the first time then it calls -(BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar
Do u guys have any other solution / way to implement this feature in a much better way than this ??
Do we have any custom made UISearchBar recent history dropdowns ??
I have searched for a custom UISearchBar recent history dropdown in cocoacontrols,code4app and cocoapods for this no hope dint find any .
Please help me with this .
For your first issue, you can add a category on UISearchBar something like this and this shall always enable your return button on keyboard when tapped on UISearchBar
#implementation UISearchBar (MyAddition)
- (void)alwaysEnableSearch {
// Loop around subviews of UISearchBar
NSMutableSet *viewsToCheck = [NSMutableSet setWithArray:[self subviews]];
while ([viewsToCheck count] > 0) {
UIView *searchBarSubview = [viewsToCheck anyObject];
[viewsToCheck addObjectsFromArray:searchBarSubview.subviews];
[viewsToCheck removeObject:searchBarSubview];
if ([searchBarSubview conformsToProtocol:#protocol(UITextInputTraits)]) {
#try {
// Force return key to be enabled
[(UITextField *)searchBarSubview setEnablesReturnKeyAutomatically:NO];
}
#catch (NSException *iException) {
}
}
}
}
For second issue, why don't you use shouldChangeTextInRange: delegate method which gets called for each entered character.
As a side note, this SO thread has a sample code to do this. This may help you.
Good luck!
I am re-writing the possible steps as per your recent clarification.
keep a flag/boolean to monitor tableview is hidden or not.
in the UISearchBar Delegate method check the serachbar's text field's [obj isFirstResponder] method.
a. if firstResponder =yes --> Show the histroy tableview OR Vice versa.After show/hide is accomplished call below method on UISearchBar' textfield.
*[searchbarobj.textfield resignFirstResponder];*
b. if firstResponder = No---> Don't do anything. leave the method.

How to show/hide a search bar inside a navigation bar (iOS 7) as in Apple's Calendar app?

I want to use a search bar button in a navigation bar to show a search bar just like Apple do in the Calendar app. The cancel button would dismiss the search bar and return the navigation bar to its former state, bar buttons, title, etc.
Using the iOS 7 property:
self.searchDisplayController.displaysSearchBarInNavigationBar = YES;
puts the search bar into the navigation bar just fine. My problem is trying to have it appear conditionally on the press of a bar button. I've tried firing this line from my button's action but no go. I've tried setActive:Animated: on the searchDisplayController
self.searchDisplayController.active = YES;
but no luck either. Any ideas or help would be appreciated.
I'm not sure if you notice, but on the Apple's calendar app when you press the search icon, it open a new UITableView with search bar. If this is what you want to do, you will have a create a UIViewController with a UITableView and a UISearchBar which inside that tableView you will be filtering the content.
If I was you, I will just hide the UISearchBar and call it whenever is needed with the button to show up.
This might work as well. Just give it a try and let me know:
In your viewWillAppear:
- (void)viewWillAppear:(BOOL)animated {
// scroll search bar out of sight
CGRect newBounds = self.tableView.bounds;
if (self.tableView.bounds.origin.y < 44) {
newBounds.origin.y = newBounds.origin.y + self.searchBar.bounds.size.height;
self.tableView.bounds = newBounds;
}
// new for iOS 7
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0] atScrollPosition:0 animated:YES];}
Now that is hidden, call this to hide it again when the search is done:
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
[self viewWillAppear:YES];
}
and to show the searchBar with a button, then:
- (IBAction)displaySearchBar:(id)sender {
// makes the search bar visible
[self.searchBar becomeFirstResponder];
}
In iOS 8 you can simply present a UISearchController and you will get the same animation as Calendar.app. Check out Apple's UICatalog sample code for an example.

SearchBar in UINavigationItem will not be first controller

I have a UISearchBar in my UINavigationItem like so:
searchBar = [[UISearchBar alloc] init];
[searchBar setDelegate:self];
self.navigationItem.titleView = searchBar;
Then in my table view I use:
-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
[self.searchBar resignFirstResponder];
}
--so that the keyboard will disappear if the user scrolls through the results.
However, now when I click on the search bar again, I can't get it to pull up the keyboard. I figured the view would do it automatically but it doesn't (clearly). I tried:
-(void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
[searchBar becomeFirstResponder];
}
It didn't work (and I didn't expect it to)
searchBarTextDidBeginEditing is not going to be called until after the search bar becomes first responder, so clearly your becomeFirstResponder call is not even being called.
I am just as surprised as you are that the search bar does not just automatically become first responder when it is tapped. Is some other code (not shown above) disabling it? Did you implement searchBarShouldBeginEditing: to return NO?
EDIT: After chat, turned out the problem was that he was not assigning the UISearchBar a frame (as you can see from his code).

UISearchBar - How can I prevent dismissing the scopeBar when the cancel button is tapped?

I want my UISearchBar's scopeButtons to remain visible at all times, but even though I've set searchBar.showsScopeBar = YES', the buttons are still dismissed with an animation if I begin a search and then cancel it.
Is there any way I can prevent the scopeBar being animated out when the search is cancelled?
Since the scope bar is only meant to be used while the UISearchController is active, I approached the problem differently.
I make the UISearchController active immediately.
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
// Immediately activating the searchController keeps scope bar permanently visible
searchController.isActive = true
// Tapping the cancel button triggers this method, which quickly toggles the scope bar
// But the cancel button isn't needed anyway, so hiding it solves the problem
searchController.searchBar.showsCancelButton = false
}
But now that the UISearchController is always active, by default the UINavigationBar is hidden, which is probably not what you want. To fix that, I prevent it from being hidden in viewDidLoad
searchController.hidesNavigationBarDuringPresentation = false
This approach means that I don't need to use showsScopeBar at all, because it is always visible while the UISearchController is active.
In case anyone is interested, the following delegate method does it.
- (BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar
{
[searchBar setShowsScopeBar:YES];
return YES;
}

Cannot get UISearchBar Scope Bar to appear in Toolbar (or anywhere) on iPad

This is really causing me fits. I see a lot of info on putting a UISearchBar in the top row of a UITableView -- but I am putting the UISearchBar into the Toolbar at the top of my screen (on the iPad). I cannot find ANYTHING regarding how to handle UISearchBar and UISearchDisplayController using a UIPopoverController on the iPad. Any more info about the UISearchDisplayController using a UIPopoverController would be greatly appreciated. Please help with this as I am at my wit's end.
Using IB, I put a toolbar on the IUView on the iPad. I added the following: Search Bar (not Search Bar and Search Display) to the toolbar. I set the options to be as follows: Show Cancel Button, Show Scope Bar, Scope Button Titles are: "Title1" and "Title2" (with Title2's radio button selected). Opaque, Clear Context and Auto Resize are checked. I hooked up the delegate of Search Bar to the "File's Owner" and linked it to IBOutlet theSearchBar.
In my viewWillAppear I have the following:
//Just in case:
[theSearchBar setScopeButtonTitles:[NSArray arrayWithObjects:#"Near Me",#"Everywhere",nil]];
//Just in case (again):
[theSearchBar setShowsScopeBar:YES];
//doesn't seem to do anything:
//[theSearchBar sizeToFit];
searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:theSearchBar contentsController:self];
[self setSearchDisplayController:searchDisplayController];
[searchDisplayController setDelegate:self];
[searchDisplayController setSearchResultsDataSource:self];
//again--does not seem to do anything..but people have suggested it:
[theSearchBar sizeToFit];
Okay, so far, I thought, so good. So, I made the File's Owner .m file to be a delegate for: UISearchBarDelegate, UISearchDisplayDelegate.
My issue: I have yet to implement the delegates necessary to do the search but still... shouldn't I be seeing the scopeBar next to the search field when I click into the search field? Just so you know I DO see the log of the characters I type, so the delegate is working.
Here is a routine I used to check to see if IB really put the Scope Bar (UISegementedControl) in the searchbar:
for (UIView *v in theSearchBar.subviews)
{
if ([v isMemberOfClass:[UISegmentedControl class]])
{
// You've got the segmented control!
UISegmentedControl *scope = (UISegmentedControl *)v;
// Do your thing here...
NSLog(#"Found Scope: '%#'\n",scope);
NSLog(#"Scope Segments: '%d'\n",[v numberOfSegments]);
}
}
This shows:
[30013:207] Found Scope: '<UISegmentedControl: 0x68a06b0; frame = (0 0; 200 44); opaque = NO; layer = <CALayer: 0x68a0600>>'
[30013:207] Scope Segments: '2'
So, I know the 2 segments are there. I also know they are not showing up...
What am i doing wrong?
Why doesn't the Scope Bar appear? A results UIPopoverController appears with the title "Results" and "No results found" (of course) when i type the first character in my search...but no scope bar. (not that i expect anything other than "No Results Found".
I am wondering where the scope bar is supposed to appear...in the titleView of the UIPopover? In the toolbar to the right of the search area? Where?
[self.searchDisplayController searchBar] setScopeButtonTitles:[NSArray arrayWithObjects:#"Near Me",#"Everywhere",nil]];
This Might Help.
UISearchBar does not display it's scope when embedded in a UIToolbar, this is true even in iOS 7.
You must build your own UISegment and add it into the table view of the search results or build your own view to hold the UISearchBar that would display scope.

Resources