Dismiss UITextView in iOS when user clicks outside - ios

In my iPhone app I have a UITextView added to my main view and I would like to dismiss it when user clicks anyplace in the screen outside of the UITextView boundaries.
Is it possible? What would be the best way to implement this?

Try using this
-(void)ViewDidLoad{
....
UITapGestureRecognizer *tapRec = [[UITapGestureRecognizer alloc]
initWithTarget:self action:#selector(tap:)];
[self.view addGestureRecognizer: tapRec];
....
}
-(void)tap:(UITapGestureRecognizer *)tapRec{
[[self view] endEditing: YES];
}
You can also use i.e optional
[textView resignFirstResponder];
In UITapGestureRecognizer
-(void)tap:(UITapGestureRecognizer *)tapRec{
[yourTextView resignFirstResponder];
}
Or if it is required on clicking next then
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
if([text isEqualToString:#"\n"]) {
[textView resignFirstResponder];
return NO;
}
return YES;
}

I recommend to turn your mainView into a UIControl.
-(IBAction)backgroundTap:(id)sender
{
[[self view] endEditing:YES];
}

Related

Keyboard not showing for UITextView after hiding it using [self endEditing:YES]

I have a UITextView that is created programmatically on viewDidLoad using the method below. Keyboard is shown successfully right after [_answerTextView becomeFirstResponder] is called. And hid if the user enters return(\n) character.
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
if([text isEqualToString:#"\n"]) {
[self endEditing:YES];
return NO;
}
return YES;
}
After the keyboard is hid by the code above, I'm not able to bring it back anymore by tapping the UITextView again.
I tried showing the keyboard by calling [_answerTextView becomeFirstResponder] on Tap event for the parent UIView and it worked. But that's not what I want.
UITextView is created by the method below;
-(UITextView*)createSurveyTextView{
_answerTextView = [[UITextView alloc]initWithFrame:CGRectMake(0, 0, _optionsStackView.frame.size.width, 200)];
_answerTextView.keyboardType = UIKeyboardTypeDefault;
_answerTextView.text = #"";
_answerTextView.editable = true;
_answerTextView.selectable = true;
_answerTextView.delegate = self;
[_answerTextView becomeFirstResponder];
_answerTextView.backgroundColor = [UIColor whiteColor];
_answerTextView.textColor = [UIColor blackColor];
_answerTextView.layer.cornerRadius = 5;
[_optionsStackView addSubview:_answerTextView];
_answerTextView.font = [UIFont systemFontOfSize:20];
[_answerTextView setReturnKeyType:UIReturnKeyDone];
[_optionsStackView bringSubviewToFront:_answerTextView];
[self bringSubviewToFront:_answerTextView];
[_answerTextView setUserInteractionEnabled:true];
UITapGestureRecognizer *mainViewTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTextViewTap:)];
UITapGestureRecognizer *tap2 = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTap2:)];
[_answerTextView addGestureRecognizer:mainViewTap];
[self addGestureRecognizer:tap2];
return _answerTextView;
}
I want the UITextView to simply show the keyboard when the user taps on it self. What am I missing?
Edit: I have the same sources in another view, but everything works fine there. The only difference is, here the UITextView is created programmatically.
Edit 2: I got it worked. The _optionsStackView that the UITextView is added as a child is a UIStackView. I tried adding the _answerTextView to the parent UIView and everything works fine now. What would be the problem with the UIStackView?
Your problem very strange in your code.You can explantion why use UITapGestureRecognizer to this UITextView control.How do you think this lead to conflict?
I find your problem where in start,but I create new project to ensure.So I confirm that UITextView already has target with itself.Also you can't to add UITapGestureRecognizer.
What you're doing is almost correct, but just try changing endEditing: to [textView resignFirstResponder]:
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
if ([text isEqualToString:#"\n"]) {
[textView resignFirstResponder];
return NO;
}
return YES;
}
If that doesn't work, then it could be that one of your gestures is preventing the UITextView's own UITapGestureRecognizer from receiving the tap. Try disabling (or comment out the creation of) both of your recognizers to verify that it is the issue. If it is, then you can fix it using the UIGestureRecognizerDelegate methods.
You did not use common way to hide/close the keyboard.
Try this common way:
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
return [textField resignFirstResponder];
}
This is a method in the UITextFieldDelegate, use it and remove your code:
if([text isEqualToString:#"\n"]) {
[self endEditing:YES];
return NO;
}
Edit:
#siburb You are right. My bad.
UITapGestureRecognizer maybe the root cause.
Edit:
#Semih Akbas
Repalce:
[_optionsStackView addSubview:_answerTextView];
To:
[_optionsStackView addArrangedSubview:_answerTextView];

keyboard not disappear when used resignFirstResponder in iOS

coding environment sierra 10.12,Xcode 8.1. Two textField in my roorView, if first textfield's text is nil, second textfield will can't be editing.When i used resignFirstResponder method to turn off keyboard in textFieldDidBeginEditing: method, keyboard not disappear. I add a fullscreen TapGesture in rootView. I'm very confused,anyone have ideas to help me deal with this problem?
`
#pragma mark -- UITextFieldDelegate
- (void)textFieldDidBeginEditing:(UITextField *)textField{
if (textField == self.password) {
[self.username resignFirstResponder];
NSString *name = self.username.text;
if ([name isEqualToString:#""]) {
[CFBlurHUD showFaild:#"sign in error!"];
[self performSelector:#selector(dismmiss) withObject:nil afterDelay:1.5f];
self.password.enabled = NO;
}
}
}
- (void)dismmiss{
[CFBlurHUD dismiss];
self.password.enabled = YES;
}
`
If you want to simply dismiss a keyboard from view, try the following:
self.view.endEditing = true;
use your UITextFieldDelegate methods specifically UITextFieldShouldBeginEditing and return NO and execute the code to show the popover instead. This way the keyboard is never shown to begin with
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
[self.view endEditing:YES];
return NO;
}
Because current textfiled is password: if (textField == self.password) {. But you set:
[self.username resignFirstResponder];
It 's not correct.
Try:
[self.username resignFirstResponder];
[self.password resignFirstResponder];
or :
self.view.endEditting = true;
use your UITextFieldDelegate methods specifically UITextFieldShouldBeginEditing and return NO and execute the code to show the popover instead. This way the keyboard is never shown to begin with
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
[self.view endEditing:YES];
return NO;
}
First step for dismiss keyboard Give textfeild delegate in storyboard
Or Also give by code :
self.txtName.delegate = self;
Dismiss keyboard when tap gesture method called:
- (void)dismmiss{
[self.view endEditing:YES];
[CFBlurHUD dismiss];
self.password.enabled = YES;
}
or Also Dismiss when touch anywhere in View:
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
[self.view endEditing:YES];
}
Or when user press return button in keyboard:
-(BOOL)textFieldShouldReturn:(UITextField *)textField{
[textField resignFirstResponder];
return YES;
}

How to hide keyboard on touch UITableView in iOS Obj-C

I am new in iOS development. I want to hide the keyboard when tapping outside of a TextField. My TextField is in a cell from an UITableView.
I have tried to follow some of those links, however without any success--
Dismiss keyboard on touch anywhere outside UITextField
Dismiss keyboard by touching background of UITableView
Hide keyboard when scroll UITableView
I am trying to find the simplest way possible.
Thanks in advance
This is the simplest way to dismiss keyboard
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
UITapGestureRecognizer *gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(hideKeyboard)];
[tableView addGestureRecognizer:gestureRecognizer];
}
- (void)hideKeyboard
{
[self.view endEditing:YES];
}
It's not about touch, only working when scroll
TableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;
also have
UIScrollViewKeyboardDismissModeInteractive // the keyboard follows the dragging touch off screen, and may be pulled upward again to cancel the dismiss
Add delegate class UITextFieldDelegate
-(BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return YES;
}
You'll need to add an UITapGestureRecogniser and assign it to the view, and then call resign first responder on the textfield on it's selector.
you can use Tap gesture to hide keyboard.
- (void) tapGesture : (UIGestureRecognizer *) gestureRecognizer {
for (UIView *subview in view.subviews) {
if([subview isKindOfClass : [UITextField class]] ) {
UITextField *tf = (UITextField *) subview;
[tf resignFirstResponder];
}
}
}
Try This code
Write following code in viewDidLoad and add UIGestureRecognizerDelegate in .h file.
UITapGestureRecognizer *singleFingerTap =
[[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(handleSingleTap:)];
[singleFingerTap setDelegate:self];
[self.view addGestureRecognizer:singleFingerTap];
// Listen for keyboard appearances and disappearances
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardDidShow:)
name:UIKeyboardDidShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardDidHide:)
name:UIKeyboardDidHideNotification
object:nil];
Delegates of keyboard Appearances and disappearances
- (void)keyboardDidShow: (NSNotification *) notif{
// Do something here
tblview.tag = 1;
}
- (void)keyboardDidHide: (NSNotification *) notif{
// Do something here
tblview.tag = 0;
}
UITapGestureRecognizer event function for hide keyboard
- (void)handleSingleTap:(UITapGestureRecognizer *)recognizer {
blview.tag = 0;
[self.view endEditing:YES];
}
UIGestureRecognizer delegate
-(BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{
if(tblview.tag == 1){
return TRUE;
}
else{
return FALSE;
}
}
I am using the solution in two parts:
To dismiss keyboard on tableview/collectionview tap:
UITapGestureRecognizer *gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(hideKeyboard)];
gestureRecognizer.cancelsTouchesInView= NO;
[self.collectionView addGestureRecognizer:gestureRecognizer];
(Don't forget cancelsTouchesInView set to NO to get touch event of tableview/collection view)
To dismiss keyboard on scroll (as tableview/collectionview are subclass of UIScrollView):
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
[self.view endEditing:YES];
}
Hope it helps somebody.
This will help you..
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.view endEditing:YES];
}
The easiest way is to alloc a tap Gesture in viewDidLoad and then hide keyboard
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
UITapGestureRecognizer *gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(hideKeyboard)];
[_tableView addGestureRecognizer:gestureRecognizer];
}
- (void)hideKeyboard
{
[self.view endEditing:YES];
}
Or on github you certainly found a library that hide your keyboard

Hide keyboard by touching the screen

I want to hide the keyboard by touching the view. Everybody recommends to use this method, saying there's no need to link or anything else, but is not working.
The problem is that my method is not called.Is there anything else that should be done?
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[[self view] endEditing:YES];
}
I had trouble with this so use a method that loops through all views seeing if they are textviews and firstResponders. Not sure of the structure of a UITextView but you might need to check for that too although it may be covered.
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
for (UIView *txt in self.view.subviews){
if ([txt isKindOfClass:[UITextField class]] && [txt isFirstResponder]) {
[txt resignFirstResponder];
}
}
}
The best approach is to create a "lock view" which is a UIView that takes over the whole screen once the textField becomesFirstResponder. Make sure it's on top of all views (well, besides the textview, of course).
- (void)loadLockView {
CGRect bounds = [UIScreen mainScreen].bounds;
_lockView = [[UIView alloc] initWithFrame:bounds];
_lockView.backgroundColor = [UIColor clearColor];
UITapGestureRecognizer *tgr = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(lockViewTapped:)];
[_lockView addGestureRecognizer:tgr];
[self.view addSubview:_lockView];
}
- (void)lockViewTapped:(UITapGestureRecognizer *)tgr {
[_lockView removeFromSuperView];
[_textField resignFirstResponder];
}
Use UITapGestureRecognizer For Dismiss keyboard.
Write this code on your viewdidload().
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:#selector(dismissKeyboard)];[self.view addGestureRecognizer:tap];
and in dismissKeyboard method put this code.
-(void)dismissKeyboard
{
[TextFieldName resignFirstResponder];
}

UITextView not resigning

Ok I have exhausted google and this site looking for an answer and cannot find one. I currently have a UITextView (postMessage) and the keyboard for it will not disappear. I have tried every possible code combination to make it dismiss but it simply will not.
I have tried doing the return key method
- (BOOL) textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
if([text isEqualToString:#"\n"]){
//MainViewController *mvc = [[MainViewController alloc] init];
//[mvc.view endEditing:YES];
//[[self view] endEditing: YES];
//[self.postMessage becomeFirstResponder];
//[self.topLayer endEditing:YES];
//[self.view endEditing:YES];
//[self.collectionView endEditing:YES];
//[self.postMessage.editable = NO];
//[postMessage resignFirstResponder];
[self.postMessage resignFirstResponder];
return NO;
}else{
return YES;
}
}
I also have tried using a UIToolBar with a UIBarButton
-(IBAction)done:(id)sender {
[self keyboardIsHidden];
[[self view] endEditing: YES];
[self.postMessage becomeFirstResponder];
[self.topLayer endEditing:YES];
[self.view endEditing:YES];
[self.collectionView endEditing:YES];
//[self.postMessage.editable = NO];
[self.postMessage resignFirstResponder];
keyboardBar.hidden = YES;
NSLog(#"done");
}
And nothing..... I have used NSLogs to make sure that both methods are being called, but the keyboard will not resign. I have also use and if statement to check to make sure the UITextView (postMessage) is firstResponder and it is.
In my project I have 2 views (not view controllers) a bottom layer view and top layer. The user pulls the top layer up into view. I also have a UICollectionView.
I have noticed that when I press the return key on the keyboard or the 'Done' key on my UIToolBar the UICollectionView reloads the data.
I do have the UITextViewDelegate set on the .h.
I also have postMessage.delegate = self in my ViewDidLoad
Thanks!
-Mike
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if([string isEqualToString:#"\n"]) {
[textField resignFirstResponder];
return NO;
}
return YES;
}
i am using this work fine
you can use like this.
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range
replacementText:(NSString *)text
{
if ([text isEqualToString:#"\n"]) {
[textView resignFirstResponder];
// Return FALSE so that the final '\n' character doesn't get added
return NO;
}
// For any other character return TRUE so that the text gets added to the view
return YES;
}
or create a button ..
-(IBAction)btnclicked{
[txtvw resignFirstResponder];
}
Attach your TextField Delegate with File owner , Clean build and run Project

Resources