Is there a delegate method that gets called when a user clicks on the dark overlay, which basically removes first responder status from the UISearchDisplayController? (I cannot find one in the docs.)
I would like to know when users click the black overlay, and the keyboard is hidden.
If you implement the UISearchDisplayDelegate then:
- (void)searchDisplayControllerDidEndSearch:(UISearchDisplayController *)controller
should be called upon tapping the overlay.
I messed around with this components a few months back but ended up not using it because you can not change its standard behavior much.
What I did found out is that it is just a wrapper for the UISearchBar, so you can access the searchBar on your SearchDisplayController like this:
[searchDisplayController.searchBar setDelegate:self];
This way gives you a bit more freedom to access the delegate methods of the searchBar component itself. Like textDidChange, cancelButtonClicked etc.
Related
I am working on a iOS project where I want to implement a search functionality. I'm using UISearchBar and UISearchDisplayController and I would like to make UISearchBar implicitly hidden. When user taps on the UIBarButtonItem, the search bar will appear and "becomeFirstResponder", whereas when user clicks on the Cancel button in the search bar, it should disappear.
The appearing is working correctly, but I have a problem with disappearing. I managed to hide the search bar when user taps on the Cancel button (searchBarCancelButtonClicked method), but I'm unable to hide the search bar when the grey (dimmed) background in UISearchDisplayController is tapped. As far as I know, there is no method to detect this event, so it is necessary to apply some hack. Do you know any, or what is the best way to detect tapping on the gray background?
So I've finally worked it out. Apart from the searchBarCancelButtonClicked:(UISearchBar *)searchBar, it is also necessary to hide the search bar in searchDisplayControllerDidEndSearch:(UISearchDisplayController *)controller. It looks this callback is called even when the gray (dimmed) background is tapped, so it can be easily used for hiding the search bar.
UISearchDisplayController usually consists of a UISegmentedControl, the UIResultsTable and the keyboard. The results table is where you want to detect this touch to dismiss. With that being known, maybe you can add a transparent UIButton to that view that dismisses first responder, or Maybe you can add a UIGestureRecognizer on a transparent view that achieves the same effect? Just thinking off the top and have not tried this myself, if it works for you im glad !
I have a modal window that's used for searching data from a remote server- it has a UITextField as the titleControl of the navbar for the window, and a tableview filling the window (that displays the results obviously). Now what I want to do is when the user scrolls the tableview, immediately have the textfield lose focus (resign first responder) so that the keyboard dismisses and the user has more room to scroll through the tableview (it stretches down to fill the gap left by the keyboard). Basically the same functionality as when using a UISearchDisplayController (or whatever it's called).
So I have this code for detecting the scroll event of the tableview:
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
[searchField resignFirstResponder];
}
Which works fine. However, the issue is that once the user scrolls the table and the textfield loses focus, you can't give focus back to it by tapping on it again. So basically once I call that [resignFirstResponser] I can never again bring the keyboard back up and edit the textfield value. Anyone have any idea why? Do I need to explicitly call [becomeFirstResponder] on the field somewhere? Because I thought that was handled automatically when the field is tapped?
Also of note- I am calling [becomeFirstResponder] on the text field right when the modal window is first called up, so the field is pre-focused. Could that have anything to do with it?
I can post more code if anyone would like, but I don't think I'm doing anything out of the ordinary with the textfield.
Thanks for any help!
You are calling the resignFirstResponder from a function which will be called everytime you scroll the UIScrollview. Hence it does not appear. You need to call resign when the uitextview goes out of focus.
You can do the following. Its a hack:
Whenever you focus on the UITextField create a invisible button to overlay your scroll view.
Capture the button press event and resign first responder
Whenever the uitextfield becomes first responder create the button
This way you will remove the bug, viz calling the method in scrollViewWillBeginDragging.
Other option would be to overrite viewDidAppear method for the uiTextField.
Or you could put your textfield into a different container and handle scrollViewWillBeginDragging by checking which scrollview sent the message.
Did u set a delegate for you searchField? I had the same issue. I popup a model view, and set the text field to be the first responder inside viewDidLoad. Everything works well for the first time. But once I dismiss the modal view controller, and reopen it. my text field cannot be focused anymore.
I found it has something to do with methods of UITextFieldDelegate. Once I remove implementation for methods
– textFieldShouldEndEditing:
– textFieldDidEndEditing:
everything works well. but don't know why
Are you doing anything with "textFieldShouldEndEditing", like #fengd?
A problem that I had was that I was viewing a modal view, and my "textFieldShouldEndEditing" routine was incorrectly returning "NO" on a specific text field. When my modal got dismissed, I would be unable to tap on any other text-field, presumably because the old text field was still "first responder". Since it can never end editing, it fouls up all other text fields that come after it.
I realize this is 2 yrs after the fact, but maybe someone else might find this useful.
I have a view that's used to display Comments. You can obviously comment from this view. Just like the Facebook application (checkin view) where there's a Comment bar on the bottom of the view. I would like to achieve the same functionality (not including the modal, which I've done already) when clicking on what looks like a UISearchBar.
I guess I just need to know what the best method for accepting touches are on a UISearchBar without actually having the keyboard popup (I would assume it's returning null or something on a specific delegate method perhaps?). Instead I'd like to call an action that simply presents my modal view. So I'm not actually going to allow the user to tap text into the UISearchBar, they'll do that within a UITextField on the modal.
Hope this makes sense and of course, answers are greatly appreciated.
Why do you want to use UISearchBar in the first place then? I'd go for either a custom view that draws something that looks like a UISearchBar, or, even simpler, just use a UIButton with an image that looks like a UISearchBar.
In case you really wanted to use the UISearchBar I guess you could subclass it and overwrite touchesBegan:, but I don't think this a good idea.
I'm trying to implement a UISearchBar within a UITableView, which behaves like the one in the "Artists" tab of the iPod application.
I have it hiding the navigation bar, and resizing the search box to show the "Cancel" button, etc. but am unable to get it to hide the section index titles.
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
inSearchMode_ = YES; // tell sectionIndexTitlesForTableView: to return nil
tableView_.scrollEnabled = NO; // works correctly, var is definitely wired
[tableView_ reloadSectionIndexTitles]; // doesn't call sectionIndexTitlesForTableView:
...
Am I missing something? Is UITableView -reloadSectionIndexTitles broken?
Typically my response to this kind of thing would be to call reloadData, but that has the side effect of causing the UISearchBar to lose focus.
I think approach you want is along these lines (Say you have a ArtistController which you want to make searchable):
Add a sub-controller to the ArtistController called ArtistSearchController
When the search box is clicked, bring the ArtistSearchController to the front as modal (to hide artists) or add transparency if you still want to show artists in the background.
When a search term is entered, created a model for the ArtistSearchController which is the data from ArtistController, filtered using the search term, and then display it in a list view
close the modal view when the user hits cancel.
This will save you from manipulating your original controller/nav bar and give it better usability
It seems what I need to do is to use a UISearchDisplayController rather than hand-rolling my own. I was able to modify the "TableSearch" sample to use sections and section headings, and it behaves as I want it to.
I have a UITextView that is properly displaying URLs thusly:
contentView.editable = NO;
contentView.dataDetectorTypes = UIDataDetectorTypeAll;
My goal is to make it so you can still tap on this text view in order to edit its text at a particular location (just like the built-in Notes app). That way, if you tap a link, it'll launch a browser, but if you tap anywhere else, it'll start editing at the point where you tapped. Should be easy, right?
Not so far. Subclassing the UITextView and overriding touchesEnded gives you a chance to set editable to YES. But when you do that, the text view doesn't remember where you tapped (the selectedRange doesn't get set properly), so editing always begins at the bottom of the text view.
I've even tried using the undocumented setSelectionWithPoint method, but it doesn't behave as you'd expect.
Can anyone think of some way to achieve a proper tap-to-edit UITextView with tappable links?
Perhaps you could try either retaining the UITouch and UIEvent or forging copies using custom classes that have the same class signatures, then re-send the touchesBegan: and touchesEnded: events after setting editable to YES.