textFieldShouldBeginEditing called multiple times
hardikdevios opened this issue · 36 comments
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?
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.
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.
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.
Thanks @hardikrocks111 for your contribution towards this library. I'll probably be come out with some solution for your case.
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.
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 .
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
Either use cocoapods or framework, but not both.
Added New and easy workaround for doing custom work in textFieldShouldBeginEditing:
delegate.
It must not all textFieldShouldBeginEditing on each field. It must call it only for the tapped text field.
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.
@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.
@seriyvolk83 If you have any better approach then please share with us.
@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.
@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.
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.
@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.
@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..
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.
@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.
Or you can right a hack and remove delegate temporary before calling canBecomeFirstResponder.
@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.
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
}
isFirstResponder
is alway false at textFieldShouldBeginEditing
until textFieldDidBeginEditing
...
@hackiftekhar your workaround solution UIControlEventTouchDown
wont work as touch events are not called on UITextField
.. plz verify?
@yasirmturk Have you tried adding UIControlEventTouchDown event since when I checked this at that time it was working correctly.
yes i did and it was not working so i used the 2nd solution unwillingly :)
Same issue textFieldShouldBeginEditing calls multiple time face in version # 4.0.8. How to handled this?
@anishparajuli555 Your method work but keyboard not hide when want to move on next screen after click on specfic textfield.
@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 andisAskingCanBecomeFirstResponder
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 handletextFieldShouldBeginEditing
issue, but after removingcanBecomeFirstResponder
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.
good decision.. keep it up
is isAskingCanBecomeFirstResponder available in 4.0.10 ?
@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
@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.
@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.
For some reason @anishparajuli555's workaround also works for me even though as explained by @yasirmturk
isFirstResponder is alway false at textFieldShouldBeginEditing until textFieldDidBeginEditing