Using UITextField with a UISearchDisplayController in place of a UISearchBar - iphone

How can I use a textfield rather than a search bar with the UISearchDisplay controller?
I want to completely customize the search bar by getting rid of the magnifying glass icon and customizing the background. Also stopping it from resizing and bringing up the 'cancel' button. I see some people using hacky ways to do this by editing parts of the search bar api that weren't supposed to be edited. So it seems the more accepted way to do customization on this level would be to use a UITextfield instead of a UISearchBar. But there doesn't seem to be ANY info on the web about doing this!
If I use a textfield, what methods do I need to call when text changes to make the UISearchDisplayController work?

The trick here is to rewrite the UISearchDisplayController. It really only does 3 things.
Move the searchbar up to the top of the view and hide the UINavigationBar.
Place a transparent cover view over the remainder of your view.
Show a UITableView with any search results.
So start by registering your UIViewController as a delegate for the UITextField and..
-(void)textFieldDidBeginEditing:(UITextField *)textField {
//here is where you open the search.
//animate your textfield to y = 0.
//I usually make the search tableview and the cover a separate view,
//so I add them to my view here.
[self.navigationController setNavigationBarHidden:YES animated:YES];
}
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSString *searchText = [[NSString alloc] initWithString:[textField.text stringByReplacingCharactersInRange:range withString:string]];
//display your search results in your table here.
}
-(void)textFieldDidEndEditing:(UITextField *)textField {
//hide all of your search stuff
[self.navigationController setNavigationBarHidden:NO animated:YES];
}

Related

How can I make the keyboard go away?

I have a app I'm making that has 2 text fields and buttons below it. When the user starts to type, the keyboard comes up and covers the buttons. Is there a way to make the keyboard go away?
There are two ways to do so
// this one line will dismiss the keyboard from anywhere in your code
[self.view endEditing:YES];
or
with the delegate of textfield (you should declare it in your .h file first)
#interface someController : UIViewController <UITextFieldDelegate>
and the in .m
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
// next line will dismiss the keyboard
[textField resignFirstResponder];
return YES;
}
Check UITextField documentation:
To dismiss the keyboard, send the resignFirstResponder message to the text field that is currently the first responder. Doing so causes the text field object to end the current editing session (with the delegate object’s consent) and hide the keyboard.
In other words, just send resignFirstResponder to an active text field object.
I use this:
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
[self.alertView dismissWithClickedButtonIndex:self.alertView.firstOtherButtonIndex animated:YES];
return YES;
}
In the view controller after setting the text field delegate to self.

resignFirstResponder for UITextField with search returnkey

Simple question: how can I resign my textfield if my "done" key is Search. Essentially, what do I do if the user does not want to search, but instead wants to cancel...
thanks
You can use: a cancel button for SearchBar and need to implement this SearchBar delegate :
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
isSearching = NO; //This is a flag which specifies if searching is going on or not.
searchBar.text = #""; //Clears out search bar text
[self resetSearch]; //Reset search resets all the flags and variables.
[self.leadsTable reloadData]; //Reloads the tableView
[searchBar resignFirstResponder]; //Resigns responder from Search bar
}
This is a proper way to resign the responder if user doesn't want to search.
Look at how you can add an in-built Cancel button in UISearchBar. Check the property "Shows Cancel Button" (Red Arrow highlight)
EDIT:
STEP-1:
Check conditionally whether your textField's text is blank? If so resignFirstResponder for the TextField. You need to set the Delegate to self for the UITextField using code:
txtField.delegate = self;
Or you can do the same from the interface builder by connecting TextField's delegate to File's Owner.
STEP-2: You need to implement this delegate method.
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
if([textField.text isEqualToString:#""])
{
[textField resignFirstResponder];
}
return YES;
}
EDIT-1:
Now create a UIToolbar with one bar button labeled 'Cancel'
Once you have done that:
You can write an button click event for UIToolBar:
-(IBAction)cancelClicked:(id)sender
{
[txtField resignFirstResponder];
}
Once you have done that you can now just write:
txtField.inputAccessoryView = toolbarOutlet;
Hope this helps you.
The text on the return button is irrelevant to the discussion. You want to know how to resign first responder without pressing the return button, and there are a few ways to do it.
Use the inputAccessoryView of the text field to display a separate cancel button in a toolbar above the keyboard.
Use a tap gesture recognizer on the field's superview to recognize when the user taps outside the field, and call [self.view endEditing:YES] (where self is your view controller). This will cause the first responder to resign. (This is very finicky in a scroll view.)
Swap out the rightBarButtonItem of the current view controller for a cancel bar button item while editing, assuming you have a UINavigationBar on screen at the time. When editing ends, swap back in the regular right bar button item, if any.

Resetting UISearchbar programmatically

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

Designing iOS SearchBar

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
}

Dismiss iphone keyboard

I am trying to recreate something similar to the popup keyboard used in safari.
I am able to visually reproduce it by placeing a toolbar over my view and the appropriate buttons, however i cant figure out any way to dismiss the keyboard once the user has touched the done button.
There is a couple of things you need to remember. The number #1 part developers forget to set is the delegate of the textField.
If you are using the Interface Builder, you must remember that you need to set the delegate of the textField to the file Owner.
If you are not using Interface Builder then make sure you set the delegate of the textfield to self. I also include the returnType. For Example if the textField was called gameField:
gameField.delegate = self;
gameField.returnKeyType = UIReturnKeyDone;
You must also implement the UITextFieldDelegate for your ViewController.
#interface YourViewController : UIViewController <UITextFieldDelegate>
Finally you need to use the textFieldShouldReturn method and call [textField resignFirstResponder]
-(BOOL) textFieldShouldReturn:(UITextField*) textField {
[textField resignFirstResponder];
return YES;
}
All your textFields will use this same method so you only need to have this setup once. As long as the delegate is set for the textField, the UITextFieldDelegate is implemented for the interface, you add the textFieldShouldReturn method and call the
resignFirstResponder your set.
Have you tried:
[viewReceivingKeys resignFirstResponder];
where viewReceivingKeys is the UIView that is receiving the text input?
If your building your own views in Interface Builder, set your view controller to be delegate for the text field and implement textFieldShouldReturn: from UITextFieldDelegate in your views controller.
- (BOOL)textFieldShouldReturn:(UITextField *)theTextField
{
NSLog(#"%# textFieldShouldReturn", [self class]);
[theTextField resignFirstResponder];
// do stuff with the text
NSLog(#"text = %#", [theTextField text]);
return YES;
}
UITextFieldDelegate textFieldShouldReturn: in the iphone cocoa docs
If you're talking about dismissing the keyboard from a UITextField rather than a UITextView. Your question isn't that clear? If you are then ensure your class is marked as a UITextFieldDelegate in the interface file,
#interface MyController: UIViewController <UITextFieldDelegate> {
UITextField *activeTextField;
// ...remainder of code not show ...
}
and then you should implement the two delegate methods as below,
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
activeTextField = textField;!
return YES;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
activeTextField = nil;
[textField resignFirstResponder];
return YES;
}
However if you're using a UITextView then things are a bit more complicated. The UITextViewDelegate protocol lacks the equivalent to the textFieldShouldReturn: method, presumably since we shouldn’t expect the Return key to be a signal that the user wishes to stop editing the text in a multi-line text entry dialog (after all, the user may want to insert line breaks by pressing Return).
However, there are several ways around the inability of the UITextView to resign as first responder using the keyboard. The usual method is to place a Done button in the navigation bar when the UITextView presents the pop-up keyboard. When tapped, this button asks the text view to resign as first responder, which will then dismiss the keyboard.
However, depending on how you’ve planned out your interface, you might want the UITextView to resign when the user taps outside the UITextView itself. To do this, you’d subclass UIView to accept touches, and then instruct the text view to resign when the user taps outside the view itself.
Create a new class,
#import <UIKit/UIKit.h>
#interface CustomView : UIView {
IBOutlet UITextView *textView;
}
#end
Then, in the implementation, implement the touchesEnded:withEvent: method and ask the UITextView to resign as first responder.
#import "CustomView.h"
#implementation CustomView
- (id)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
// Initialization code
}
return self;
}
- (void) awakeFromNib {
self.multipleTouchEnabled = YES;
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(#"touches began count %d, %#", [touches count], touches);
[textView resignFirstResponder];
[self.nextResponder touchesEnded:touches withEvent:event];
}
#end
Once you’ve added the class, you need to save all your changes, then go into Interface Builder and click on your view. Open the Identity inspector in the Utility pabel and change the type of the view in your nib file to be your CustomView rather than the default UIView class. Then in the Connections Inspector, drag the textView outlet to the UITextView. After doing so, and once you rebuild your application, touches outside the active UI elements will now dismiss the keyboard. Note however that if the UIView you are subclassing is “behind” other UI elements, these elements will intercept the touches before they reach the UIView layer. So while this solution is elegant, it can be used in only some situations. In many cases, you’ll have to resort to the brute force method of adding a Done button to the navigation bar to dismiss the keyboard.
use a navigation controller and pop the view when done?
for example, I use code like this to slide an about box in:
[[self navigationController] presentModalViewController:modalViewController animated:YES];
and then when the button in that about box is clicked, I use this to get rid of it:
[self.navigationController dismissModalViewControllerAnimated:YES];
In my case the about box occupies the whole screen, but I don't think it would have to for this to work.
edit: I think I may have misunderstood your question. Something along the lines of my code would be if you are faking the whole keyboard view yourself. I think that resign first responder is the right way to do it if it is the normal keyboard with your toolbar added on top.