What's the best way to determine which UITextField triggers the method -(BOOL)textFieldShouldBeginEditing:(UITextField *)textField (or any of the other UITextFieldDelegate methods)? I've seen code like this before:
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
if (textField == textFieldCode) {
return YES;
}
return NO;
}
but this only works if I have textFieldCode as an ivar in my class, and in this case I'm just initializing a couple of UITextFields and putting them in a table, so I don't have references to them in the class.
I was thinking that I could use the hash function and store the hashes for each textField somewhere in the class, and then compare textField's hash to the desired hash in the method call, but that seems like kind of a hack.
Since you only have a couple of fields, you can assign unique numbers to the tag properties of each textfield to enable identification.
You can have an iVar of NSArray that will contain all the text fields.
Then just enumerate through it to find out which text field sent the message
Related
This may seem like a very simple question, however I haven't been able to discover a simple option yet...
I have a series of UITextFields followed by a UITextView. How can I incorporated the TextFields and the TextView in the same method below.
-(BOOL) textFieldDidBeginEditing:(UITextField *) textField{
textField = activeField;
if([self.textField1 isFirstResponder]){activeField = textField1;}
else if([self.textField2 isFirstResponder]){activeField = textField2;}
else if([self.textField3 isFirstResponder]){activeField = textField3;}
else if([self.textView1 isFirstResponder]){ activeField = textView1;}
[scrollView1 scrollRectToVisible:[activeField frame] animated:YES];
return NO;
}
The last line causes a warning of:
Incompatible pointer types assigning to 'UITextField *_strong' from 'UITextView *_strong'
This is due (I'm sure) to the obvious fact that the UITextField and the UITextView are different Objects... which is fine however is there a way to get around this as I wish to be able to advance through the textFields and TextViews with a next and previous button.
as per this method
-(void) nextTextField:(id)sender{
if([self.textField1 isFirstResponder]){activeField = textField2;}
else if([self.textField2 isFirstResponder]){activeField = textField3;}
else if([self.textField3 isFirstResponder]){activeField = textView1;}
else if([self.textView1 isFirstResponder]){ activeField = textField1;}
}
I was hoping for a casting sort of option however I am a little confused as to how to cast in objective C... This might sound dumb however
activeField = ((UITextField) textView1);
is how I'd have cast in Java but it seems I just can't seem to get he syntax right.
Should I cast to a UIView as they both inherit from that?
Thank you in advance
Okay, so you don't need to store activeField, for this method, so the only relevant code would be your nextTextField: method. Try changing it to:
-(void) nextTextField:(id)sender{
if([self.textField1 isFirstResponder]) {[textField2 becomeFirstResponder];}
else if([self.textField2 isFirstResponder]) {[textField3 becomeFirstResponder];}
else if([self.textField3 isFirstResponder]) {[textView1 becomeFirstResponder];}
else if([self.textView1 isFirstResponder]) {[textField1 becomeFirstResponder];}
}
You don't need to cast to a different type or anything.
I think you have a few issues with your thinking. You will need to go down two levels to get to a common super type. Both UITextField and UITextView are "visible" components so they inherit from UIView. They can both be cast to UIView but not to each other. But this won't help you with your question. I think you may be struggling with delegation also.
The method textFieldDidBeginEditing: is a delegate call and it only works with UITextField. This is why the class that contains your method above should implement UITextFieldDelegate. When you set focus to the UITextField, UITextField first checks to see that the delegate is not nil. If the delegate property holds a class then UITextField checks to see if it implements the textFieldDidBeginEditing: method explicitly. If the method is implemented in the delegate then the UITextField calls the method.
It is no different with the UITextView. However UITextView doesn't even know about the textFieldDidBeginEditing: method. It has its own delegate and its own method that performs the same general function as textFieldDidBeginEditing:. The UITextView version of this method is called textViewDidBeginEditing:. Like the UITextfield the UITextView checks that the delegate is not nil and that it implements textViewDidBeginEditing:. If these requirements are met then UITextView will textViewDidBeginEditing. However UITextView will never call textFieldDidBeginEditing:.
Finally objects cannot be cast into something they're not. They can only be cast as its own type or any of its ancestors.
You will need to set up both each components' method (textFieldDidBeginEditing and textViewDidBeginEditing) for this to work.
Hope this helps.
This is the text field delegate method but i have doubt about return type
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return NO;
}
and this is the same method with different return type
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
by both we can hide key board in i phone . but what is the meaning of return type "YES" or "NO". I am not seeing any difference.
In addition to the other answers here (which essentially confirm there's no major difference, no auto-resigning of the first responder by returning YES, etc.), I've discovered a strange occurrence completely dependent on the return value, specifically for a UITextField with autocorrection.
Assume the following scenario:
You have a UITextField with autocorrection enabled
You've implemented the delegate method something like this (where the text field gets resigned):
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
if (textField == self.myAutocorrectingTextField) {
[self.myAutocorrectingTextField resignFirstResponder];
}
return YES;
}
You run the app, type "Cable" into the text field, then press the return key, resigning it as first responder.
The outcome when returning YES:
The text field's text will have been changed from "Cable" to "Cables"!
I have tested a handful of other words that respond similarly:
"Stuff" changed to "Stuffs"
"Ten" to "Tens"
And, one time "Car" changed to "Carl", another time "Car" changed to "Carp"
The outcome when returning NO:
Normal. The text field's text will not have been changed.
In Summary...
When returning YES, the text field may autocorrect already-correct words. It does not, however, present one of those "autocorrect text bubbles", because these are legitimate words.
When returning NO, the text field will not autocorrect already-correct words.
Note:
In both cases, incorrectly-spelled words will always be corrected. For example:
If you were to type "Wev", an "autocorrection text bubble" should appear with the text "Web". If you hit the Return key, regardless of the delegate's return value, the text will be replaced with the correction.
One difference that I see based on personal experience is that if you return YES, auto correction and auto capitalization are triggered, if you return NO, they are not. There might be other things done, but that's all I could notice so far.
That's what they mean by "default behavior".
The most important difference I've found is that if the text field emits the control event UIControlEventEditingDidEndOnExit, this will cause the text field to resign first responder unless textFieldShouldReturn is implemented to return NO.
The textFieldShouldReturn is a place where you can handle the Return button on the keyboard.
textFieldShouldReturn asks the delegate if the text field should process the pressing of the return button.
If you implement your own code to process the return button you should return NO, or return YES for it to be handled in the default way.
The IOS Docs state:
The text field calls this method whenever the user taps the return button. You can use this method to implement any custom behavior when the button is tapped.
http://developer.apple.com/library/ios/#DOCUMENTATION/UIKit/Reference/UITextFieldDelegate_Protocol/UITextFieldDelegate/UITextFieldDelegate.html
I have 2 textFields side by side, countryCodeTextField and cellphoneTextField
On countryCodeTextField. I have an action selectCountry that happens on Edit Did Begin on the countryCodeTextField
- (IBAction)selectCountry:(id)sender {
countryCodeTextField.delegate = self;
[countryCodeTextField resignFirstResponder];
Note that self implements the <UITextFieldDelegate>.
Problem is when user click's cellphone the keyboard is displayed if he clicks on countryCodeTextField the keyboard is never dismissed.
If the person clicks the countryCode first then the keyboard never appears(which is what I want).
Why isn't the keyboard hidden when the user clicks cellphoneTextField first and then countryCodeTextField?
If you don't want the user to be able to edit a particular UITextField, set it to not be enabled.
UITextField *textField = ... // Allocated somehow
textfield.enabled = NO
Or just check the enabled checkbox in Interface Builder. Then the textfield will still be there and you'll be able to update it by configuring the text. But as sort of mentioned in comments, users expect UITextFields to be editable.
Also, why are you setting the delegate in the IBAction callback? I would think you'd be better off doing this in Interface Builder or when you create the UITextField in code.
EDIT:
Ok - so you want users to be able to select the box, but then bring up a custom subview(s) from which they select something which will fill the box.
So set the UITextField delegate when you create it (as mentioned above) and implement the following from the UITextFieldDelegate protocol:
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
return NO;
}
to return NO. Note that if you are using the same delegate for both of your UITextFields, you will need to make this method return YES for the other field. For example, something like:
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
if (textField == countryTextField)
return NO;
return YES;
}
Hopefully this should stop the keyboard being displayed - and now you have to work out how to fire your own subviews, which I'd suggest doing via an IBAction (touch up or something perhaps). You'll have to test various things out here, but remember you're kinda corrupting the point of UITextField and maybe it'll work and maybe it won't, and maybe it'll break in the next iOS upgrade.
Okay, so first, I think you shouldn't be using a UITextField. I think you should be using a UIButton and have the current value showing as the button's title. However, if you have your heart set on it, I would use our good friend inputView, a property on UITextField, and set that to your custom input view (which I assume is a UIPickerView or similar.)
This has the added bonus of not breaking your app horribly for blind and visually impaired users, something you should probably be aware of before you go messing about with standard behaviour.
In your method :
- (IBAction)textFieldDidBeginEditing: (UITextField *)textField
call this :
[textField becomeFirstResponder];
and apply checks for the two fields i.e., when textField is the countryCodeTextField write :
[textField resignFirstResponder];
and call your method :
[self selectCountry];
In this method display the list of country codes.
So Your code will be :
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
return YES;
}
- (IBAction)textFieldDidBeginEditing: (UITextField *)textField{
[textField becomeFirstResponder];
if (textField == countryCodeTextField){
[textField resignFirstResponder];
[self selectCountry];
}
}
-(IBAction)selectCountry{
//display the list no need to do anything with the textfield.Only set text of TextField as the selected countrycode.
}
I have a UITextField in a custom section header. There are multiple sections using this style of header, and therefore multiple UITextFields.
I have implemented the UITextFieldDelegate. When I edit one of these UITextFields, it calls the delegate method textFieldDidEndEditing. How do I determine which section header this UITextField was in? I need to save the value to core data in the appropriate NSManagedObject for that section.
Many thanks in advance
EDIT: Several people have suggested using a tag of the section number when creating the cell, which would work perfectly. However, I have already assigned the UITextField a tag to distinguish it as a 'header' textfield as opposed to a cell textfield or a 'footer' textfield. There are a whole lotta textfields on this table!!
Further EDIT: Using in indexPath has been suggested. This would be my preferred solution if I can get it to work. Does anyone know if headers and footers have indexPaths?
You could use tags to identify UITextField instances. Since you're already setting tags in UITextField instances, set the tags on the section views itself:
- (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIView *sectionView = ... // your section view instance
// assign the section index as the tag
sectionView.tag = section;
return sectionView;
}
In the textfield delegate, get the section index from the sender's parent:
- (void) textFieldDidEndEditing:(UITextField *)textField;
{
NSInteger theSectionIndex = textField.superview.tag;
// your custom logic here
}
You would probably want to look into UITableView method indexPathForCell:.
You can get the cell through view hierarchy from your UITextField, since it's in your Cell's contentView.
Regards,
sven.
It is very simple Mr.Ben Thompson. You have named different between each one to UITextFields am i right?. Just find the specific UITextField by used it's name.
-(void) textFieldDidEndEditing:(UITextField *)textField
{
if (textField == textfieldOne)
{
//Do whatever you want...
}
else if (textField == textfieldTwo)
{
//Do whatever you want...
}
else if (textField == textfieldThree)
{
//Do whatever you want...
}
}
I hope it will help you a little bit. Thanks.
i believe you add the field as a custom view to the header in viewForHeader method of tableview.
I suggest keeping a tag of the field using the section like this.
textfield.tag == section;
then in the delegate message you can have a switch method to compare tags..and do your own code there
there are two different textfields in my applications and i set the .delegate property of both of them to: self.
Now i implemented different methods from the uitextfielddelegate protocol but i want to be able to control the two textfields individually. For instance i want the first text field to do something different when editing begins than the second textfield... Is the only solution to this problem to set the assign a different delegate or is there a way to do this with both of the textfield having the same delegate assigned to them?
I hope my question is understandable i tried it to explain the best way that i could.....
thanks in advance!
Set a tag on the textfield on initialization, then check the UITextField object that is passed into the delegate method's tag, then you'll be able to make a differentiation between the two textfields:
#define FIELD_ONE_TAG 1
#define FIELD_TWO_TAG 2
UITextField *textFieldOne = ...
textFieldOne.tag = FIELD_ONE_TAG;
...
UITextField *textFieldTwo = ...
textFieldTwo.tag = FIELD_TWO_TAG;
- (void)textFieldDidBeginEditing:(UITextField *)textField {
if(textField.tag == FIELD_ONE_TAG) { //field one
} else {//field two
}
}
UITextField *textFieldOne=.....
UITextField *textFieldTwo=....
- (void)textFieldDidBeginEditing:(UITextField *)textField {
if(textField == textFieldOne)
{ // field one code
}else{
//field two code
}
}
have two references of the inserted text views and u can compare them at the delegate methods. Not much needed with tags