I want to hide keyboard when a user presses return in UITextView object in iphone. However, mysteriously this is not working for UITextView but working for UITextField. I am unable to figure out why...
This is what I did:
1) I created a view based application in XCode4.
2) in .xib created UITextView, UITextField and UIButton objects
3) Marked both UITextField and UITextView delegates to File's Owner in Outlets
4) Added <UITextFieldDelegate> to #interface UIViewController in .h
5) Added textFieldShouldReturn function in .m
Here are the codes:
.h file
#interface keyboardDisappearViewController : UIViewController <UITextFieldDelegate>
{
UITextView *textBoxLarge;
UITextField *textBoxLittle;
}
#property (nonatomic, retain) IBOutlet UITextView *textBoxLarge;
#property (nonatomic, retain) IBOutlet UITextField *textBoxLittle;
- (IBAction)doSomething:(id)sender;
#end
.m file
- (BOOL) textFieldShouldReturn:(UITextField *)theTextField
{
NSLog(#"textFieldShouldReturn Fired :)");
[textBoxLarge resignFirstResponder];
[textBoxLittle resignFirstResponder];
return YES;
}
Amazingly, the keyboard is disappearing in case of textBoxLittle (UITextField) but not in case of textBoxLarge(UITextView)
As a further check I, made the button to call function doSomething
- (IBAction)doSomething:(id)sender {
[textBoxLarge resignFirstResponder];
[textBoxLittle resignFirstResponder];
}
When I am pressing the button, keyboard is disappearing in both textboxes.
Its driving me nuts why textFieldShouldReturn is working for small textbox, but NOT for large textbox.
Please Help!
Three things:
Make your view implement UITextViewDelegate.
#interface keyboardDisappearViewController : UIViewController
<UITextFieldDelegate, UITextViewDelegate>
Add the following method:
- (BOOL)textView:(UITextView *)textView
shouldChangeTextInRange:(NSRange)range
replacementText:(NSString *)text
{
if ([text isEqualToString:#"\n"])
{
[textView resignFirstResponder];
}
return YES;
}
Set the file's owner as delegate for the UITextView in the interface builder.
(BTW: Solution copied from the comments to the previous answer, as it took me a while to extract. I though others could benefit from my experience.)
You need to write code in UITextViewDelegate and assign it to your class.
Simple trick
Set delegate for your text view and then
doSomething
{
}
action connect to ext view for control event didEndOnExit and tuchupinside
// To dismiss key board when user clicks enter/return
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
if([text isEqualToString:#"\n"])
{
[textView resignFirstResponder];
return NO;
}
return YES;
}
Use this code
Inherit UITextViewDelegate protocol in your Viewcontroller add the text
#interface YourViewController () <UITextViewDelegate>
In viewDidLoad set yourself as a delegate:
yourUITextView.delegate = self;
Implement the delegate method below:
- (BOOL)textViewShouldBeginEditing:(UITextView *)textView
{
return NO;
}
Key Points
Someone needs to be listening for the Return Key press
UITextFieldDelegate
textFieldShouldReturn(textField : UITextField)
Someone needs to manually dismiss the keyboard
resignFirstResponder()
#1: Create a UITextFieldDelegate and assign it as the delegate to your UITextField -
exampleTextField.delegate = yourUITextFieldDelegate;
#2: Have 'yourUITextFieldDelegate' contain the following -
func textFieldShouldReturn(textField : UITextField) -> Bool {
self.titleField.resignFirstResponder(); //Here's the key!!!!!
return true; //true just says 'default behavior'
}
If you came here looking for the Swift solution, like I did, here you are :)
extension keyboardDisappearViewController : UITextViewDelegate {
func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {
if(text == "\n") {
textView.resignFirstResponder()
}
return true
}}
You have coded in the .h file:
#interface keyboardDisappearViewController : UIViewController <UITextFieldDelegate>
{
UITextView *textBoxLarge;
UITextField *textBoxLittle;
}
#property (nonatomic, retain) IBOutlet UITextView *textBoxLarge;
#property (nonatomic, retain) IBOutlet UITextField *textBoxLittle;
- (IBAction)doSomething:(id)sender;
#end
It should be:
#interface keyboardDisappearViewController : UIViewController <UITextFieldDelegate>
{
UITextView *textBoxLarge;
UITextField *textBoxLittle;
}
#property (nonatomic, retain) IBOutlet UITextField *textBoxLarge;
#property (nonatomic, retain) IBOutlet UITextField *textBoxLittle;
- (IBAction)doSomething:(id)sender;
#end
Related
I have several UITextView subviews, all using the same custom input interface (basically a numberpad with an autofill-option and a save button).
My problem is that the delegate method shouldChangeCharactersInRange: is not called when the textfield's text is modified from my custom keyboard (it does work when pasting text from clipboard into the textfields and also when using the standard numberpad keyboard). The text of the textfields change, but the delegate method to prevent invalid entries is not called. Other delegate methods of style DidBeginEditing: are called always.
despite of what is said in this SO LINK the documentation states that the shouldChangeCharactersInRange: delegate method will be called: "The text view calls this method whenever the user types a new character or deletes an existing character."
What am I missing?
relevant code parts:
ViewController.h:
#interface ManualPositionViewController : UIViewController <UITextFieldDelegate> {
LocationEntryTextField *latitude;
}
#property (nonatomic, retain) IBOutlet LocationEntryTextField *latitude;
#property (nonatomic, retain) IBOutlet LocationKeyboard *locationKeyboard;
..
ViewController.m:
#synthesize latitude;
#synthesize locationKeyboard;
self.latitude.inputView = locationKeyboard;
self.latitude.delegate = self;
- (void)textFieldDidBeginEditing:(LocationEntryTextField *)aTextField {
NSLog(#"textFieldDidBeginEditing called!");
self.locationKeyboard.currentTextfield = aTextField;
}
- (BOOL)textField:(LocationEntryTextField *)editedTextField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)replacementString {
NSLog(#"shouldChangeCharactersInRange called!");
NSCharacterSet *decimalSet = [NSCharacterSet decimalDigitCharacterSet];
if ([[replacementString stringByTrimmingCharactersInSet:decimalSet] isEqualToString:#""]) {
NSLog(#"Result: YES");
return YES;
}
else {
NSLog(#"Result: NO");
return NO;
}
}
LocationKeyboard.h:
#import <UIKit/UIKit.h>
#import "LocationEntryTextField.h"
#interface LocationKeyboard : UIView {
LocationEntryTextField *currentTextfield; // track first responder
}
#property (weak) LocationEntryTextField *currentTextfield;
- (IBAction) numberButtonPressed:(UIButton*)sender;
- (IBAction) backspaceButtonPressed:(UIButton*)sender;
#end
- (IBAction) numberButtonPressed:(UIButton*)sender {
NSString *entryString = #"test";
[self.currentTextfield replaceRange:self.currentTextfield.selectedTextRange withText:entryString];
}
LocationEntryTextField.h:
#interface LocationEntryTextField : UITextField
..
This line:
[self.currentTextfield replaceRange:self.currentTextfield.selectedTextRange withText:entryString];
doesn't result in a call to textField:shouldChangeCharactersInRange:replacementString:. Is that what you are expecting?
Since you are explicitly changing the text of the text field, there is no "typing" going on.
The proper way to have your custom keyboard update the text field is to call the 'insertText:` method. This method will properly deal with any selection, moving the cursor, and calling delegate methods.
Edit: You may wish to look at my answer here for a complete custom keyboard setup (minus the actual buttons).
I would like to NSLog something when my UITextView is done editing.
I've tried
- (BOOL)textViewShouldEndEditing:(UITextView *)textView
and
- (void)textViewDidEndEditing:(UITextView *)textView
neither worked.
fix:
myTextView.delegate = self;
do you set the delegate of your textview?
fix:
set delegate in .h file like this:
#import <UIKit/UIKit.h>
#interface TextViewController : UIViewController <UITextViewDelegate>
{
UITextView *textView;
}
#property (nonatomic, retain) UITextView *textView;
#end
If you are using UITextField instead make sure to use UITextFieldDelegate and not UITextViewDelegate. And this method instead, that fixed my problems.
- (void)textFieldDidEndEditing:(UITextField *)textField
I am new to IOS and can't seem to get this to work , I have an input filed on my app,from which I want to hide the keyboard whenever the user either presses return or the associated button (searchGo)
The following is my code :
mainViewController.h
#interface kepnMainViewController : UIViewController <kepnFlipsideViewControllerDelegate, MKMapViewDelegate>
{
MKMapView *_mapView;
IBOutlet UITextField *searchBox;
IBOutlet UIBarButtonItem *searchGo;
IBOutlet UIBarButtonItem *searchNearby;
MKAnnotationView *annotationView;
}
#property (strong, nonatomic) MKMapView *_mapView;
#property (strong, nonatomic) MapAnnotation *annotation;
#property (strong, nonatomic) UIPopoverController *flipsidePopoverController;
#property (strong, nonatomic) MKAnnotationView *annotationView;
#property (strong, nonatomic) UIBarButtonItem *searchGo;
- (IBAction)showInfo:(id)sender;
- (IBAction)searchGo:(id)sender;
- (IBAction)showNearby:(id)sender;
- (IBAction)searchBoxReturn:(id)sender;
- (void) setPlaceMarker: (CLLocationCoordinate2D) coord :(NSString*) title :(NSString*) subtitle;
#end
Appropriate .m snippet
-(IBAction)searchGo:(id)sender
{
NSLog(#"sender object %#",sender);
[sender resignFirstResponder];
NSLog(#"search button pressed and textbox = %#",searchBox.text);
}
-(IBAction)searchBoxReturn:(id)sender
{
NSLog(#"search box return ");
[sender resignFirstResponder];
}
Sorry if this is a dumb question but what am I doing wrong.??
UIBarButtonItem isnt an UIView and therefore definitely not an UIResponder. Instead, it's a subclass of NSObject, which doesn't respond to - (void)resignFirstResponder.
(solution: remove the [sender resignFirstResponder]; lines)
So if your view is manually programmed than you might add the following check to your code:
if ( [sender isKindOf: [UIResponder class]] == YES && [(UIResponder*)sender canResignFirstResponder] == YES )
[sender resignFirstResponder];
If you want to hide keybord on button tap assuming your searchBox is current responder than you should write
[searchBox resignFirstResponder]; // This will close keyboard
I have a UITableView tableHeaderView defined in a nib file. The tableHeaderView contains a UITextView. The UITextView's delegate is set to the UITableViewController and the UITableViewController supports the UITextViewDelegate protocol. The UITableViewController is setting various properties in the tableHeaderView including the UITextView's text and that all works fine. But textFieldShouldReturn:(UITextField *)textField in the UITableViewController never gets called and I can't get the keyboard to close after I've tapped the UITextView.
I've tried every suggestion I can find in the docs and various posts, but no luck. None of the examples I've found have this specific case of a UITextView inside a tableHeaderView.
Is there something special I need to do. Has anyone done this successfully?
I've tried setting the UITextView delegate in code, but no luck.
#class Decision;
#interface DecisionDetailViewController : UITableViewController <UINavigationControllerDelegate, UITextViewDelegate> {
Decision *decision;
UIView *tableHeaderView;
UITextView *nameTextField;
}
#property (nonatomic, retain) Decision *decision;
#property (nonatomic, retain) IBOutlet UIView *tableHeaderView;
#property (nonatomic, retain) IBOutlet UITextView *nameTextField;
#end
#implementation DecisionDetailViewController
#synthesize decision;
#synthesize tableHeaderView;
#synthesize nameTextField;
- (void)viewDidLoad {
self.navigationItem.rightBarButtonItem = self.editButtonItem;
if (tableHeaderView == nil) {
[[NSBundle mainBundle] loadNibNamed:#"DecisionDetailHeader" owner:self options:nil];
self.tableView.tableHeaderView = tableHeaderView;
}
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[nameTextField resignFirstResponder];
return YES;
}
textFieldShouldReturn is a method of UITextFieldDelegate and not UITextViewDelegate. Thats probably your problem.
I am trying to make my editable UITextView resign the keyboard (resignFirstResponder) when the user taps "Done." Using a UITextField, I have been able to do this with the following code:
- (IBAction)doneEditing:(id)sender {
[sender resignFirstResponder];
}
... and then to attach it to the relevant UITextField in Interface Builder to the action "Did End on Exit."
However, with a UITextView, I can't seem to access the "Did End on Exit" action. Any suggestions on how to make this happen?
The accepted answer didn't work for me. Instead, the following delegate method should be invoked like this:
- (BOOL) textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
if([text isEqualToString:#"\n"]){
[textView resignFirstResponder];
return NO;
}else{
return YES;
}
}
Paste that into the class that you assign to be the UITextView delegate and it'll work.
new Answer
On your View, you'd have a UIBarButton ("Done") that is connected to the IBAction below:
- (IBAction)doneEditing:(id)sender {
[textView resignFirstResponder];
}
Where textView is your textView outlet defined in your .h file and connected in Storyboard or .xib file. Like this:
#property (retain, nonatomic) IBOutlet UITextView *textView;
old Answer
Check the following:
Is UITextViewDelegate specified
in .h
Implement delegate method
for uitextview:
textViewShouldEndEditing, return YES
make sure your .m (controller) is the
delegate for uitextview in IB
resignFirstResponder should now
work.
You can implement UITextViewDelegate and wait for "\n", in Swift 4 :
myTextView.delegate = self
// ...
extension MyViewController : UITextViewDelegate {
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
if text == "\n" {
textView.resignFirstResponder()
return false
}
return true
}
}
To have the done button dismiss the keyboard and resignFirstResponder you have to implement a delegate method.
In your .h implement the UITextFieldDelegate
#interface YourViewController : UIViewController <UITextFieldDelegate>
Then implement the textFieldShouldReturn in your .m
-(BOOL) textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
Don't forget to link the delegate of UITextField to the file's Owner (very important)