Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

textFieldShouldBeginEditing called multiple times #88

Closed
hardikdevios opened this issue Oct 10, 2014 · 36 comments
Closed

textFieldShouldBeginEditing called multiple times #88

hardikdevios opened this issue Oct 10, 2014 · 36 comments
Assignees

Comments

@hardikdevios
Copy link

hardikdevios commented Oct 10, 2014

This method is calling multiple times if I disable Toolbar, it will not call multiple times, but I want your toolbar.

-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField{

return YES;

}

in my App, i have a Country text field where I don't want the user to type so when user tap on that text field it should open my popup or modal .. so any workaround?

@hackiftekhar
Copy link
Owner

When textField is requested to test that it can become first responder using '[textField canBecomeFirstResponder]; then it asks for it's delegate via 'textFieldShouldBeginEditing' that it can become first responder or not.

I'm asking for 'canBecomeFirstResponder' in 'IQUIView+Hierarchy.m' line no. 118.

I tried by adding controlEvents action on textField, but no luck.

We really need to find out a solution for this case.

@hackiftekhar
Copy link
Owner

For now you can use my open source control named IQDropDownTextField to show country list. It'll fullfil your current need without any interruption in development. But really we need a solution for your case.

@hardikdevios
Copy link
Author

Yes no problem bro i have managed this by using button in place of textfield for now ... actaully i am also trying to modify your code but looks like your obsserver textfieldviewdidbeging editing is getting all siblings to manage the next previous button .. i will surely going to contribute in your awsom library but i am in middle of very huge project and also too busy in weekend but will surely going to contribute once again thanks for your awsom lib , cheers mate.

@hackiftekhar
Copy link
Owner

Thanks @hardikrocks111 for your contribution towards this library. I'll probably be come out with some solution for your case.

@hackiftekhar
Copy link
Owner

Workaround added for your case:-
Please check Doing custom work on textField with returning NO in textFieldShouldBeginEditing: delegate:- section in README.md file.

Also updated demo project. Please check Special Case section.

@hardikdevios
Copy link
Author

cheers mate , Thanks Bro and Happy Diwali also i have read your mail and good to know that this lib is getting popular and also i am doing some little bit marketing of this lib in my colleagues and team-mates and they also giving me thanks as their keyboard issue are solved without writing a single code .. so a big thanks from my side. hopefully i am going to free after Diwali and will help you to optimise your code .

@zzpan
Copy link

zzpan commented Oct 24, 2014

when i use the cocoa pods , there is a error :Undefined symbols for architecture i386:
"OBJC_CLASS$_IQKeyboardManager", referenced from:
objc-class-ref in LoginViewController.o
ld: symbol(s) not found for architecture i386

update:
use cocoa pods , also need to drag .framework , woca

@hackiftekhar
Copy link
Owner

Either use cocoapods or framework, but not both.

@hackiftekhar
Copy link
Owner

Added New and easy workaround for doing custom work in textFieldShouldBeginEditing: delegate.

@seriyvolk83
Copy link

It must not all textFieldShouldBeginEditing on each field. It must call it only for the tapped text field.

@seriyvolk83
Copy link

How to turn off this useless feature? It's definitely wrong. What is the reason of calling it on each field? I want to show dropdown list instead of editing the field, but focusing on ANY text field my dropdown is opened because you call textFieldShouldBeginEditing on EACH field.

@hackiftekhar
Copy link
Owner

@seriyvolk83 looks like you didn't neither read Manual Management Guide or read the comments of this issue. textFieldShouldBeginEditing doesn't directly called by my library. The library is calling native canBecomeFirstResponder method to know if a textField can become first responder or not, and the iOS call textFieldShouldBeginEditing internally. So library is not directly responsible to calling this method but the iOS SDK. That's why I've added some workaround to overcome with this situation.

@hackiftekhar
Copy link
Owner

@seriyvolk83 If you have any better approach then please share with us.

@seriyvolk83
Copy link

seriyvolk83 commented Oct 30, 2016

@hackiftekhar Right, I already found this documentation. But as a new user it's very unpredictable for me on how it works by default. May be you need to turn off this by default and a developer will manually turn on if he needs this. Currently you change the expected behavior iOS. What for example if this lib is added to an existing app just for one work. If textFieldShouldBeginEditing is used in another places this library will introduce bugs that are not clear and will be found only when users will start to use it.

@seriyvolk83
Copy link

@hackiftekhar textFieldShouldBeginEditing means "textField Should Begin Editing". If I tap on a particular field, then why you ask other fields? They never should begin being edited in this case.
I think if the default behavior of this method is to return YES, and if it is invoked twice on the tapped field then why not to add another custom method instead of canBecomeFirstResponder that can be invoked on each field and textFieldShouldBeginEditing will be invoked only once at the end (as it works in iOS). Developers can use that new method to do what they want instead of working around.

@hackiftekhar
Copy link
Owner

100% Correct @seriyvolk83

textFieldShouldBeginEditing means "textField Should Begin Editing".

So this method expect to return YES or NO, so why you are writing your main work inside that method. You should only write logic to decide return YES or NO.

@seriyvolk83
Copy link

@hackiftekhar Because I don't want the keyboard to appear. If I will return just NO, then I will have no ability to show a dropdown list instead. So, I do it here. If I will move dropdown logic into another method, then I will have to return YES here and the keyboard will appear for a moment.

@seriyvolk83
Copy link

@hackiftekhar What is the reason of having text field that exists and just return NO in textFieldShouldBeginEditing? We would never can edit it. Why to have the field, then? For disabling the field we have a special flag, so..

@hackiftekhar
Copy link
Owner

I know my bro @seriyvolk83 this is why I suggested some workarounds.

Library uses canBecomeFirstResponder method for calculating toolbar previous/next buttons state accurately. Most of the people need next/previous to work properly that's why this enabled by default. If you would like to totally get rid of this nonsense then you can simply set enableAutoToolbar to NO. So you'll not get multiple callbacks in that delegate method.

@seriyvolk83
Copy link

seriyvolk83 commented Oct 30, 2016

@hackiftekhar Looks like you right. And this is a bug of iOS because in documentation there is the following:

Before becoming the first responder, the text field calls its delegate’s textFieldShouldBeginEditing(_:) method. Use that method to allow or prevent the editing of the text field’s contents.

So, textFieldShouldBeginEditing definitely should not be called from canBecomeFirstResponder.

May be the better place for my dropdown is becomeFirstResponder() method.

Or you can right a hack and remove delegate before calling canBecomeFirstResponder.

@seriyvolk83
Copy link

seriyvolk83 commented Oct 30, 2016

Or you can right a hack and remove delegate temporary before calling canBecomeFirstResponder.

@hackiftekhar
Copy link
Owner

@seriyvolk83 Cannot do that because when textField is enabled then only delegate method know if a textField can become first responder or not. That's why system use delegate method, otherwise if I write your suggested hack then canBecomeFirstResponder will always return YES if textfield is enabled.

@anishparajuli555
Copy link

I too faced this problem..A way to solve this is

func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
      
      if  textField == genderTxtField && textField.isFirstResponder {
          
          genderTxtField.resignFirstResponder()
          //do your work
          return false
          
      }
      return true
  }

@yasirmturk
Copy link

isFirstResponder is alway false at textFieldShouldBeginEditing until textFieldDidBeginEditing ...

@yasirmturk
Copy link

@hackiftekhar your workaround solution UIControlEventTouchDown wont work as touch events are not called on UITextField .. plz verify?

@hackiftekhar
Copy link
Owner

@yasirmturk Have you tried adding UIControlEventTouchDown event since when I checked this at that time it was working correctly.

@yasirmturk
Copy link

yes i did and it was not working so i used the 2nd solution unwillingly :)

@Shahbaz-Akram
Copy link

Same issue textFieldShouldBeginEditing calls multiple time face in version # 4.0.8. How to handled this?

@Shahbaz-Akram
Copy link

@anishparajuli555 Your method work but keyboard not hide when want to move on next screen after click on specfic textfield.

@hackiftekhar
Copy link
Owner

hackiftekhar commented Apr 1, 2017

@ALL, Due to seeing too many issues reported for textFieldShouldBeginEditing call multiple times, I know it's due to the Apple API's limitation. But I decided to remove validating canBecomeFirstResponder calls to fix this issue for IQKeyboardManager library, so textFieldShouldBeginEditing delegate method will not be called multiple times, but developers need to update their logic they wrote with isAskingCanBecomeFirstResponder. This variable will also be deprecated and will be removed in future releases.

This is my action plan:-

  • Current CocoaPods version is 4.0.8. In next couple of days 4.0.9 will be pushed to CocoaPods with some bug fixes and improvements. 4.0.9 will be swift 3.1 compatible version.
  • After 4.0.9, necessary changes will be made to remove canBecomeFirstResponder method call and isAskingCanBecomeFirstResponder will be put into the deprecated property list with warning text to inform developers about this. This code will be pushed to master.
  • After successful testing of new changes regarding canBecomeFirstResponder we'll push 4.1.0 to CocoaPods (probably after 1 month of 4.0.9).
  • In upcoming releases isAskingCanBecomeFirstResponder will be removed from library since this property was come to existence as a workaround to handle textFieldShouldBeginEditing issue, but after removing canBecomeFirstResponder method call, this property will make no sense.

Let me know if anyone has any thoughts or suggestion on this. I would love to hear.

@yasirmturk
Copy link

good decision.. keep it up

@kumardiwa
Copy link

kumardiwa commented Jun 17, 2017

is isAskingCanBecomeFirstResponder available in 4.0.10 ?

@hackiftekhar
Copy link
Owner

@kumardiwa the property is there in 4.0.10, but this property no longer has any effect since I did some other code changes to remove the need of this property. For now this property will always return NO.

This will completely be remove in v4.0.11

@kumardiwa
Copy link

@hackiftekhar My case is, I've 3 textfields in a viewcontroller but I want 1 of them should not be editable and I want some action when this textfield should begin editing so How can I do this. Even though I've desable IQKeyboard ( IQKeyboardManager.sharedManager().enableAutoToolbar = false) in this View controller in viewWillApear method but still got the problem.

@hackiftekhar
Copy link
Owner

@kumardiwa So from now what will happen, when you tap on the enabled textfield then the delegate method will only be get called for that text field only and not for other textfields, so you can safely write your logic inside textFieldShouldBeginEditing and return NO for the textfield which you don't want to editable.

@kuyazee
Copy link

kuyazee commented Jul 4, 2017

For some reason @anishparajuli555's workaround also works for me even though as explained by @yasirmturk

isFirstResponder is alway false at textFieldShouldBeginEditing until textFieldDidBeginEditing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants