I'd like to dismiss the keyboard with a text field using
- (BOOL)textFieldShouldReturn:(UITextField *)textField {, but I need to do the same with a text view, so I'll use - (BOOL)textViewShouldReturn:(UITextView *)textView {. Is it possible to put them togheter in the same AppDelegate?
Thank you.
Yes, you can have two delegates
#interface ViewController : UIViewController<UITextFieldDelegate,UITextViewDelegate>
Unfortunately
The protocol UITextViewDelegate does not have, something like this.
- (BOOL)textViewShouldReturn:(UITextView *)textView {
UITextViewDelegate Protocol,
EDIT 1 :
Button press event to hide the keyboard.
-(IBAction) yourButtonPressed:(id)sender;{
for(UIView *v in self.view.subviews){
if([v isKindOfClass:[UITextField class]] || [v isKindOfClass:[UITextView class]]){
if([v isFirstResponder]){
[v resignFirstResponder];
break;
}
}
}
}
I don't fully understand your question...
Basically you will do the following:
implement the UITextFieldDelegate and UITextViewDelegate in your
viewController
implement the methods of that delegates, you need/want
resignFirstResponder / endEditing of the textField / textView, where
ever you want
Just subscribe to the delegates from your viewController and make sure to set the delegate on those objects to your viewController.
.h
#interface YourViewController : UIViewController <UITextFieldDelegate, UITextViewDelegate>
.m
someTextField.delegate = self;
someTextView.delegate = self;
From the sound of it you just need to tie into the actions of the textField and textView. Create an IBAction and tie it to what you'd like. Then you can resignFirstResponder from that IBAction.
Use this action for both your textField and textView
- (IBAction)lowerTheText:(id)sender
{
[sender resignFirstResponder];
}
Yes, with a UITextView it's tricky. As I say in my book...
http://www.apeth.com/iOSBook/ch23.html#_uitextview
...on the iPad, the problem of dismissing the keyboard doesn't arise because the user can dismiss it with the button in the lower right corner of the keyboard. So this leaves only the iPhone. You will typically have an interface such that there is a Done button or similar. Look at how the Notes app solves this, for example.
The process itself is just the same: call endEditing: on the superview and whoever is first responder will cease being first responder and the keyboard will retire.
Yes, you can use textfield delegate and textview delegate in the same application.
TextField:
#interface ViewController : UIViewController<UITextFieldDelegate,UITextViewDelegate>
// This allocates the textfield and sets its frame (or) you can use interfaceBuild
UITextField *textField = [[UITextField alloc] initWithFrame:
CGRectMake(20, 50, 280, 30)];
textField.delegate=self;
// This method enables or disables the processing of return key
-(BOOL) textFieldShouldReturn:(UITextField *)textField{
[textField resignFirstResponder]; // this is event for hide keyboard.
return YES;
}
TextView:
// init
UITextView *textView = [[UITextView alloc] initWithFrame:
CGRectMake(20, 50, 280, 30)];
- (void)textViewDidChangeSelection:(UITextView *)textView
{
[textField resignFirstResponder]; // this is event for hide keyboard.
}
Related
I have designed a keyboard on my app Now I have the query is that whenever somebody tap on the textfield the keyboard on the device appear which i don't want
is there any way to disable the keyboard so that the user can see the keyboard designed on this app.
In your ViewController add the delegate of the UITextField :
#interface ViewController : UIViewController <UITextFieldDelegate>
While Creating the UITextField or in ViewDidLoad:
self.myTextField.delegate = self;
In your implementation file:
#pragma mark - UITextFieldDelegate
-(void)textFieldDidBeginEditing:(UITextField *)textField
{
[textField resignFirstResponder];
}
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
return NO;
}
Note that you can set the return of textFieldShouldBeginEditing to NO or YES according to your needs, in your case you may return YES , but provide the logic of displaying your custom keyboard
-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
return NO;
}
And Needs to add delegate <UITextFieldDelegate>
In this method you also can write code to show your custom keyboard.
lol
Set the inputView to a zero sized view:
textField.inputView = [[UIView alloc] initWithFrame:CGRectZero];
You can use following approach to restrict keyboard display when user tap on it :
Method : 1
-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
return NO;
}
This method hide the Keyboard and dont show the cursor.
Method : 2
UIView* HideView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 1, 1)] autorelease];
textField.inputView = HideView;
This method hide the Keyboard, but Cursor is appear.
You can disable user interaction.
textField.userInteractionEnabled = NO;
Is it possible to dismiss the keyboard when you have MULTIPLE UITextFields ? If so how ?
As a side note, do I have to dismiss the keyboard for Each and Every field or can it be done globally ? Oh and it would be super cool if I don't have to touch the DONE button, I'd ideally like a solution that where the user touches anything BUT the field in question and the keyboard automagically disappears...
Oh and if you'd be so kind step by step instructions.
I should have added that I have a method already to resign the keyboard....
However, it only runs when my form is submitted! (see method below)
My question is how to the keyboard to hide/dismiss without having to jump thru so many damned hoops! You'd figure after 6 years, a mature operating system would have a way to GLOBALLY hide the keyboard....NOT!
Ok, enough whining....
- (void)hideKeyboard {
[self.dancePlace resignFirstResponder];
[self.danceGate resignFirstResponder];
[self.danceTerminal resignFirstResponder];
[self.danceText resignFirstResponder];
[self.danceDate resignFirstResponder];
[self.danceStyle resignFirstResponder];
[self.danceTimeOut resignFirstResponder];
}
And this is called when my button is submitted....
- (IBAction)addListingPressed:(id)sender {
// NSLog(#"BUTTON PRESSED");
[self hideKeyboard];
[self valuesAdded];
}
My question, assuming anyone can answer this...and I suspect not, is there a way to globally hide the keyboard if the following conditions are MET: 1.) the user taps OUT of any one of the existing fields, 2.) presses anywhere else on the screen. 3.) Is no more than a line or two in the existing viewcontroller.m file. 4.) I don't have to add a confusing button on the viewcontroller. (any time I have to add outlets, the damned thing is crashing on me...and then nastiness happens, and really...remember I am JUST a beginner, and its very confusing to read that I have to place this here and that there...oy. Simple folks, simple. I'm not looking for elegant solution, just so that it works.
I have a super class that all my view controllers inherit from. In that class I have this code.
MySuperViewController.h
#import <UIKit/UIKit.h>
#interface MySuperViewController : UIViewController
#property(strong, nonatomic) UITapGestureRecognizer *backgroundTapGestureRecognizer;
#end
MySuperViewController.m
- (void)viewDidLoad{
//add a tap gesture recognizer to capture all tap events
//this will include tap events when a user clicks off of a textfield
self.backgroundTapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(onBackgroundTap:)];
self.backgroundTapGestureRecognizer.numberOfTapsRequired = 1;
self.backgroundTapGestureRecognizer.cancelsTouchesInView = NO;
[self.view addGestureRecognizer:self.backgroundTapGestureRecognizer];
}
- (void)onBackgroundTap:(id)sender{
//when the tap gesture recognizer gets an event, it calls endEditing on the view controller's view
//this should dismiss the keyboard
[[self view] endEditing:YES];
}
I have the UITapGestureRecognizer as a public property, so I can override it if I need to.
subclass
MyViewController.h
#import <UIKit/UIKit.h>
#import "MySuperViewController.h"
#interface MyViewController : MySuperViewController<UIGestureRecognizerDelegate>
#end
MyViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
//You don't always want the keyboard to be dismissed, so you tie into the gesture recognizer's delegate method
//By doing this, you can stop the endEditing call from being made
[self.backgroundTapGestureRecognizer setDelegate:self];
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
//touch.view is the view that recieved the touch
//if this view is another textfield or maybe a button, you can return NO and the endEditing call won't be made
if (touch.view == self.myViewThatShouldNotBeBlocked) {
return NO;
}
//if you want the gesture recognizer to accept the event, return yest
return YES;
}
I uploaded an example project to github.
https://github.com/JeffRegan/KeyboardBeGone
RDVKeyboardAvoiding is a scroll view with a tap gesture recognizer, designed for multiple textViews/textFields. It keeps track of the active view and removes a lot of boilerplate code.
tap anywhere outside the textField .. it will hide it..
[self.view endEditing:YES];
There are couple of other ways to do it.
[myEditField resignFirstResponder];
[myEditField endEditing];
[parentView endEditing];
If you dont wont to do so many things and simply want to dismiss keyboard than give iboutlet to each of your text filed to following method..
-(IBAction)hidekeyboard:(id)sender
{
[sender resignFirstResponder];
}
Yes, you only have to dismiss it for the one that is currently being edited.
In order to know which one is being edited, you can check the -(BOOL)isFirstResponder property, which will return YES if it is the first responder (the one being edited) or NO if it is not. Once you know which one is the first responder you can call -(void)resignFirstResponder on that one to get rid of the keyboard.
For example, if you have a method called -(void)aMethod that you want to dismiss the current view controller and you have an array of textViews called textArray, you could do a little loop such as:
-(void)aMethod {
for (UITextField *text in self.textArray) {
if ([text isFirstResponder]) [text resignFirstResponder];
return;
}
}
This way, you can have a variable number of textFields and it will still work.
If you only have one or two textFields and you do not want to create an Array object, you could do (assuming the fields are named text1 and text2:
-(void)aMethod {
if ([text1 isFirstResponder]) [text1 resignFirstResponder];
else if([text2 isFirstResponder]) [text2 resignFirstResponder];
}
Also, to make things easier for the future you could create a category method for UIView (which is what I do) to get the current first responder if it exists as a subview of that view:
#implementation UIView (GetFirstResponder)
- (UIView *)getFirstResponder {
if ([self isFirstResponder]) return self;
else {
for (UIView *subview in self.subviews) {
UIView *firstResponder = [subview getFirstResponder];
if (firstResponder) return firstResponder;
}
}
return nil;
}
You can put this method on the top of any file that you want to call it from, or create a separate file for it and import it.
Once you have this method, you can call:
- (void)aMethod {
UIView *view = [self.view getFirstResponder];
if (view) [view resignFirstResponder];
}
[superview endEditing:YES]; // superview can be the view controller's view property.
In my app I have a view that is a form that has quite a few inputs.
When the UITextField calls textFieldDidBeginEditing, it checks the tag and will bring up a UIPopoverController or the keyboard depending on the what the input is meant to be.
If the keyboard is up, I need it disappear when the user presses a textfield that brings up the popover. However I cannot make it disappear, I have tried every way to get rid of the keyboard but it just stays there. I have tried:
calling resignFirstResponder in textFieldDidEndEditing
calling [self.view endEditing:YES] in textFieldDidEndEditing
calling resignFirstResponder AND [self.view endEditing:YES] in textFieldDidBeginEditing checking for the previous tag is equal to a keyboard input text field.
Any ideas would be great.
I have ripped it out and and put it in a example project if anyone wants to see the exact behaviour.
http://dl.dropbox.com/u/61692457/KB_Test.zip
Declare a Global UITextField in .h file
UITextField *txtfld;
Replace Your method textFieldDidBeginEditing with textFieldShouldBeginEditing and now write this code
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
if (textField.tag == 1 || textField.tag==3)
{
if(numPickerPopover == nil)
{
numPicker = [[[NumPicker alloc] initWithStyle:UITableViewStylePlain] autorelease];
numPicker.delegate = self;
numPickerPopover = [[UIPopoverController alloc] initWithContentViewController:numPicker];
[numPickerPopover setPopoverContentSize:CGSizeMake(60.0, 260.0f)];
}
[numPickerPopover presentPopoverFromRect:textField.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
[txtfld resignFirstResponder];
return NO;
}
if (textField.tag == 2)
{
txtfld = textField;
return YES;
}
return YES;
}
To dismiss the keyboard when the user touches the textField that brought it up, add this method:
- (IBAction)dismissKeyboard:(id)sender {
[textField resignFirstResponder];
}
In Interface Builder, connect this method to the textField event you want, like touch up inside (or whatever is more appropriate).
I created a form and the keypad (Numeric only) appears when entering data like your age.
I want the keyboard to disappear when the user taps the background and I want to add a "Done" button in the empty slot under the 7 (next to the zero). (im using the Number Pad keyboard)
I found this example but I have a few questions.
In
-(void)viewDidLoad
{
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(dismissKeyboard)]; [self.view addGestureRecognizer:tap];
}
-(void)dismissKeyboard
{
[aTextField resignFirstResponder];
[aTextField1 resignFirstResponder];
[aTextField2 resignFirstResponder];
[aTextField3 resignFirstResponder];
}
If I have more than 1 text field in my form.
Will I need to write every textfield in the dismissKeyboard method?
Easy way to do this is to use the method provided in UIView
- (BOOL) endEditing:(BOOL)force;
This method looks at the current view and its subview hierarchy for the text field that is currently the first responder. If it finds one, it asks that text field to resign as first responder. If the force parameter is set to YES, the text field is never even asked; it is forced to resign.
So just do this:
-(void)dismissKeyboard {
[self.view endEditing:YES];
}
and it will support any more text fields you add on your page (under that UIView of course)
You should only send dismissKeyboard to that textField that you are currently editing.
In your code you have got memory leak. Better use this one:
-(void)viewDidLoad
{
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(dismissKeyboard)];
[self.view addGestureRecognizer:tap];
[tap release];
}
To check if UITextField is currently in edit mode you can check its property:
A Boolean value indicating whether the text field is currently in edit mode. (read-only)
#property(nonatomic, readonly, getter=isEditing) BOOL editing
For example, you have 3 text fields then dismissKeyboard will look something like this:
-(void)dismissKeyboard
{
UITextField *activeTextField = nil;
if ([textField1 isEditing]) activeTextField = textField1;
else if ([textField2 isEditing]) activeTextField = textField2;
else if ([textField3 isEditing]) activeTextField = textField3;
if (activeTextField) [activeTextField resignFirstResponder];
}
I use the same functionality in many of my apps. Rather than using the GestureRecognizer, I set my view up as a UIControl, rather than a UIView. You can still do the things you'd do with a UIView, but you can also assign IBActions to be performed when interacting with the view.
Here's how to do it:
In Interface Builder, select your view. Then, assign its class to UIControl. (It's probably set up as UIView currently.
In your ViewController for that view, write an IBAction method to detect backgroundTaps. Mine looks like this:
- (IBAction)backgroundTap:(id)sender
{
if ([textField1 isEditing]) {
[textField1 resignFirstResponder];
} else if ([textField2 isEditing]) {
[textField2 resignFirstResponder];
}
}
Finally, in Interface Builder, connect the IBAction you created to the UIControl.
Read this article, it may help you
Writing iOS 4 Code to Hide the iPhone Keyboard (Xcode 4)
Here i give common text field object. and asign reference to it in "textFieldShouldBeginEditing" method. that will common for all text field..
In this case, you need to dismiss one text field that will hide keyboard..
declare textfield object in .h file.
#interface RootViewController : UIViewController
{
IBOutlet UITextField* txt_common;
}
IN .m file
- (void)viewDidLoad {
[super viewDidLoad];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(dismissKeyboard)];
[self.view addGestureRecognizer:tap];
[tap release];
}
-(void)dismissKeyboard
{
NSLog(#"hi");
[txt_common resignFirstResponder];
}
#pragma mark TextField methods
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
NSLog(#"hi++++++++++++++++++");
txt_common=textField;
return YES;
}
I have set the delegate of my textfield to self and I have added the delegate for it in the .h, but I have a problem. I want the keyboard to hide If I click anything but the textfield in the view. Is this possible? If so, how would I do it?
I found a simpler way to hide the keyboard and it works when you click on the screen way.
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
// endEditing: This method looks at the current view and its subview hierarchy for the text field that is currently the first responder.
// If it finds one, it asks that text field to resign as first responder
[[self view] endEditing:TRUE];
}
You can do some "hacking"... Like this:
- (void)textFieldDidBeginEditing:(UITextField *)textField{
//glass is a class's property
if(glass){
self.glass=nil;
}
glass=[[UIButton alloc] initWithFrame:CGRectMake(0, 0, 320, 480)]; //put the size you want.
[glass addTarget:self action:#selector(hideGlass) forControlEvents:UIControlEventTouchUpInside];
[self.view insertSubview:glass belowSubview:textField];
}
-(void)hideGlass{
//remove your glass.
[glass removeFromSuperview];
//your textField resigns first responder.
if([myTextField canResignFirstResponder]){
[myTextField resignFirstResponder];
}
}
So basically what you do, is to add a dummy button right bellow your textField. So when you touch anything else, excepts your textField, he will make your textField resignFirstResponder and removes himself from the view.
Edit 1 ( the tweek) You just need to replace this:
if(glass){
self.glass=nil;
}
for this:
if(glass){
[glass release];
glass=nil;
}
You just need to implement the following delegate methods:
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return YES;
}
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {
[textField resignFirstResponder];
return YES;
}
If you have an IBOutlet for the UITextField, you can dismiss the keyboard using [textField resignFirstResponder];. This being said, you will have to implement event listeners for everything else on the view. If you want the keyboard to hide when the user taps the view's background, it can be done through a touch event in the view controller's implementation:
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[textField resignFirstResponder];
}
If you have any buttons or subviews, you will have to implement individual touch events or actions for those as well.