I have a navigation bar with added searchbar icon.
Tapping the searchbar button instantiates the UISearchBarController.
Everything works fine, except that the 'Cancel' button tap propagates to the navigation bar button below (which closes the current modal).
Tapping cancel here:
Also taps done here:
I've witnessed that there is a delegate method available:
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
}
How do I stop the event from propagating?
Note: The propagation doesn't happen when tapping 'Cancel' after text was entered in the searchbar, only when it is empty. Very strange.
I think what you are seeing is that tapping Cancel when text is present is actually clearing out the text within the UITextField that the UISearchBar owns (as part of the UISearchController). Tapping Cancel otherwise is supposed to dismiss the search bar. From the Apple docs on searchBarCancelButtonClicked: it states that:
Typically, you implement this method to dismiss the search bar.
I've ran into this in the past with "search bar" functionality on a UITableViewController, and it's one of the reasons why I've switched over to using a standard UIViewController which owns a UITableView and owns a UISearchBar. I have a little bit more control, this way, over the content of my view controller, and the search bar I'm using with it.
Not sure if that directly helps you, but using a UISearchBar instead of a UISearchController might point you in a better direction like it did for me.
Rebooting the emulator fixed the problem, whatever that makes sense.
Related
I have a view controller with a UISearchController that, when tapped, will expand and bring up the keyboard. I want the user to press a button (separate from the search controller), when then brings up the search bar without actually tapping it. Is this possible?
What you want to achieve is to make the searchBar become the first responder. You can do that with:
searchController.searchBar.becomeFirstResponder()
On the iPhone in Landscape orientation, there is a button in the lower right corner that causes the keyboard to dismiss. I really don't want this button to be there, since I have a Done button already and users should only be able to stop editing the textfield by pressing this Done button (which has to be there to address portrait orientation anyway).
I'm wondering if there's a way to remove that keyboard dismissal button, or if not, I'd appreciate any suggestions for UITextField delegate behavior that differentiates between proper dismissal (Done button pressed) and improper (first responder might resign even though Done button not pressed, e.g. because of aforementioned problem button or view controller dismissal).
One thing you can do is declare a variable, something like, isDismissedProperly and initiate it to false. Then subscribe to keyboard show and hide notifications. UIKeyboardDidShowNotification and UIKeyboardDidHideNotification. In the target method for done button(as mentioned in the question), change the isDismissedProperly to true. And in the keyboardDidHide method, you can check if isDismissedProperly is true or false.
If it's true, then user dismissed the keyboard by pressing done button.
Hope it helps!
I have a simple TableView with a search bar added. Everything works fine, except that when the view comes up (it's the first view in the app), the search bar is focused (or appears so), so that it shows the "Cancel" button (see image).
I've tried setting the tableview as first responder, calling resignFirstResponder on the search controller etc.
If you tap on the search bar and then hit cancel, the focus is removed and everything's fine - the "Cancel" button goes away.
Any ideas on why this is and how can I show a search bar that's not focused?
Add searchBar.resignFirstResponder() in viewDidLoad() method.
-Good Luck.
Based on the image, your textfield is not first responder and you just don't want to see cancel button
you can set searchBar.setShowsCancelButton = false
or in storyboard, uncheck Shows Cancel Button
then if you want to show cancel button during editing, check the UISearchBarDelegate methods:
func searchBarTextDidBeginEditing
and set searchBar.setShowsCancelButton = true
func searchBarCancelButtonClicked
and set searchBar.setShowsCancelButton = false
I am facing an issue with the UISearchController in iOS 8. The problem is that whenever I am clicking on cancel button, instead of cancelling the search operation, it is bringing up the keyboard.
Follow below steps to reproduce the issue -
Click on the search bar.
Type a word and click on search(This will
dismiss the keyboard)
Now click on cancel.
Now, instead of dismissing the search, the keyboard is popping up for entering the text. This usually happens when I am tapping at the right half of cancel button and it can be reproduced even in standard iOS apps like Contacts app. I would like to dismiss search when cancel is tapped.
Is there any workaround for this issue?
You could remove the search bar as a first responder programatically when the cancel button is clicked which will prevent the keyboard from coming up.
[searchController.textField resignFirstResponder];
So I had created a very simple custom NavigationController a couple years ago, of course it subclasses UINavigationController and the only method it overrides is
- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item
in it I show a UIAlertView asking the user to make sure they want to go back. When they select yes it goes back using
[self popViewControllerAnimated:YES];
Everything is working right except for with iOS 7 when using the new swiping from left to right gesture to go back to the previous screen.
It correctly goes back to the previous screen however the top navigation bar doesn’t change.
For example if I’m on my main screen and I click on Row1. The view will change and the nav bar will display Row1 as the title and a ‘< Back’ button on the top left.
Clicking on the ‘< Back’ button works 100% as expected.
If I swipe left to right to go back, the view will go back to my main screen however the nav bar will still be showing the ‘< Back’ button and ‘Row1’ as the title.
I tried just using UINavigationController instead of my custom class which subclasses it and the swiping features work correctly so I know that’s the problem. I must be missing a call or something in my custom class
Any ideas?
Thanks!
EDIT:
I just edited my CustomNavigation code a bit and it now seems to work. When using the top left Back button for some reason shouldPopItem was getting called twice, so I had some code to make it work correctly with iOS 6 and lower.
When using the swipe gesture I noticed that it was only being called once and the first time I was popping the controller but returning NO (which was why the nav bar wasn't changing). I now put a check for iOS 7 and return YES right away which fixed the problem and now works properly.
navigationBar:shouldPopItem: is a delegate method on UINavigationBar, which UINavigationController implements. So all you're doing is stopping the navigation bar from popping a UINavigationItem. That's why when you override this that it prevents the navigation bar from removing the item associated with the UIViewController being popped. It shouldn't actually ever prevent the navigation controller from popping a view controller, and it was probably just a side effect of the old implementation that made it work right. Either they changed something, or there's just a difference with how it works when the gesture is used, that makes this hack no longer work right. Anyway, generally you're not supposed to be able to prevent the back button from going back. If you want to present a screen that requires some kind of confirmation to go back, or a task to be completed or cancelled first, you should present a modal view controller instead. Otherwise, you could replace the default back button with your own and hide the normal back button. Then your custom button (which would look different unless you went to a lot of work) could call a custom method to prompt first.
Of course you'll want to disable the pan gesture if you stick with using a UINavigationController. There's a property on UINavigationController to get the gesture recognizer:
#property(nonatomic, readonly) UIGestureRecognizer *interactivePopGestureRecognizer NS_AVAILABLE_IOS(7_0);
You can disable it so that it will no longer make you go back.