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.
Related
I have a UIScrollView with 2 views, side by side, each of which covers the entire screen.
They are moved to visible bounds on user's action, only one covering the screen at a time. Both of these views have multiple UITextFields. Working with the simulator, I fill in a textField in the first view and when I press the Tab key, the firstResponder is assigned to a textField in the other view. I understand that on using the device, the user will not be able to do that. But what if the user uses a bluetooth keyboard, or similar accessory? I do not want a textField, that is currently not visible to become firstResponder. Can this be done?
EDIT: I just remembered the canBecomeFirstResponder method. But how do I determine which textField is about to becomeFirstResponder?
It sounds like the problem isn't that they shouldn't be able to tab between the two text fields, but instead that they shouldn't be able to edit a text field that isn't visible, and they should be able to tab between them if they are both visible at the same time.
Instead of restricting tab, I would implement the UITextField delegate method -textFieldShouldBeginEditing:, which allows you to return a boolean whether or not that text field should become the first responder.
Something such as:
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
// Only edit if the text field is visible
return !textField.isHidden;
}
You may need to adjust this code to fit your 'is visible' status of the text field.
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.
I have modified the code of Apple's sample iOS project TableSearch in order to use it for searching a webservice by parsing its contents. Everything I have implemented works fine except for one ugly detail when performing a search using the SearchDisplayController's SearchBar. I have changed the behaviour of the SearchDisplayController to make it call my search function first when the "Search" button was tapped.
The problem is that when the search iteration (which is performed in the background in an NSOperationQueue) is finished the "searchResultsTableView" (of the searchDisplayController) is not automatically displayed or not assigned the resulting content. If you then change the SearchBar's text or tap the "Cancel" button from the view which appears when you touch the search field (see TableSearch) the correct TableView appears with the search results. I simply want to have this step to be executed right after the search operation is finished, so before you interact. At this stage the "No Results" label is currently displayed. The methods "filterContentForSearchText" and "shouldReloadTableForSearchString" are unchanged from the original TableSearch project.
I have taken a look at different class references of the SearchDisplayController and its attributes but I could not find any final solution yet.
I have tried the following in a section which is definitely iterated after the NSOperation is finished but it does not seem to solve the problem.
[self.searchDisplayController.searchResultsTableView removeFromSuperview];
and
self.searchDisplayController.searchResultsTableView.hidden = YES;
These operations both have the correct view I want displayed BUT scrolling is disabled until you change the state so that the view is hidden again. It is possible to select TableView cells, though. I basically want to have this just with scrolling enabled...
Thanks in advance for your effort!
I have same problem and I just solved it. I had exactly same problem, I wanted disable instant search and when I hit search button, the table didn't load but when I clicked cancel, it loaded up. And If I scroll on table view that didn't load correct result after search, it crashed due to index out of bound.
The thing you need to do is reload searchResultTableView not current tableview. After you filter out your data by search term, put
[self.searchDisplayController.searchResultsTableView reloadData]
to reload your search result, and it will shows up after you hit search button.
Hope this help
I found that setting the searchBar.text causes searchDisplayController.searchResultsTableView be added to self.view, I solve it like this:
self.searchBar.text = #"xxxx";
[self.searchDisplayController.searchResultsTableView removeFromSuperview];
I am looking for the most direct way to make it so that when the user taps a UITableViewCell, a keyboard appears. I want to use a custom keyboard (UIPickerView) and I preferably would like to make the cell style UITableViewCellStyleValue2. I can't seem to find a very direct way of doing this. I have a navigation bar on top, and hoping to make the buttons on that change as well...
Thanks!
First and foremost, to achieve this you're going to have to handle the custom animation of the UIPickerView sliding up and down. They keyboard is handled automatically by the controls that automatically need it (UITextField, UITextView, etc.).
So when your view loads you will want to create and configure your picker and then move its Y coordinate to CGRectGetMaxY([[UIScreen mainScreen] applicationFrame]);
Then in your - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath you will call a method that is responsible for animating your picker view into place. The only problem I foresee with this approach is allowing the user to dismiss this picker view in a way that makes sense as users are used to input views sliding only when they're needed (meaning that they appear when a view becomesFirstResponder and they disappear automatically when that view resignsFirstResponder status).
I think I understand what you're trying to achieve here and I would do it a bit differently. Instead of displaying a picker with options when you select a cell I would instead push a new tableViewController with your options laid out as cells. Then when the user makes a selection, you can set a checkmark and pop back to the original view.
I seem to be having a problem with the titles in my application.
Let me describe what is happening here.
1) starts out good with the correct image
http://img262.imageshack.us/img262/5808/picture15b.png
2) still good after clicking a cell
http://img31.imageshack.us/img31/4440/picture13dvg.png
3) after hitting the backbutton previous title remains and the last one is gone
http://img150.imageshack.us/img150/5689/picture14ltq.png
4) however after scrolling up and down fast enough the correct view appears again
http://img262.imageshack.us/img262/5808/picture15b.png
As you can see in the images above I'm using a UITableview however I'm NOT using the navigationItem title , I'm using a UILabel ( called title ).
When I click on my cells and scroll through my application everything is fine however when I click my backbutton, which is also not a standard backbutton from the tableview, but a UIBarbuttonItem it just pops the last view (and does some other stuff too)( the button below as seen in my imagelinks).
-(void)back_clicked:(id)sender
{
[self.navigationController popViewControllerAnimated:YES];
....
}
It appears that my Titles do not refresh when I press the back button(which makes sense I guess since i do not have some sort of a refresh function ).
I concluded this because when I scroll down really fast my original title comes back.
I noticed but could be wrong , bear with me here , that reloadData applies mostly to table ,cell constructing and such so I assume this is not the one I'm looking for.
So is there some sort of refresh function I can use ?
I would really like some suggestions ;)
thnx all for reading
If when you h it the back button you are coming back to another viewController i would suggest looking at the method viewWillAppear from UIViewController, you can override this method and call it before you go back, in the method implementation you can set the correct title ...reference http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instm/UIViewController/viewWillAppear:
How are you inserting the UILabel that you use as a title?
Like this: [self.navigationController.navigationBar.titleView = < label >];
or more like this: [< top window > addSubview: < label >];
I've never had any problems with custom title views using the first method.