iphone: uitextfield, multiple textfields with the same delegate? - iphone

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

Related

cast UITextView to UITextField

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.

How to determine which section header in UITableView is being edited

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

Setting limits to TextBox and TextView in Xcode

I have created a Window based application with the Tab-bar as the RootViewController. On one of the tabs, I've provided a TextBox and TextView. I want to limit the number of characters that can be written inside them (i.e. TextBox and TextView).
Please help if someone knows how to do it..
Thanks..
what do you mean by "tab bar" and "tab"?
i assume you have a UITabBarController as RootViewController and a some subclass of UIView is one of the tabs that is shown when tapping on a TabBarItem.
furthermore i assume your UITextView and (UITextField?) is added to that UIView subclass and NOT the TabBarItem?
if that's the case, you could do a check using the text property:
if([yourTextView.text length] > 42) {
// truncate text; e.g. throw away last part or first part until the length is below 42
}
should be the same for a UITextField - just use the text property again
You should implement the UITextFieldDelegate and/or UITextViewDelegate methods,
textField:shouldChangeCharactersInRange:replacementString:
or
textView:shouldChangeTextInRange:replacementText:
respectively.
Set an instance of the class that implements those methods as the delegate for your view. The logic in the method should examine the incoming text and decide what to do based on the length.
I've found another similar way to implement this problem using Delegates:
#define MAX_LENGTH 20
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if (textField.text.length >= MAX_LENGTH && range.length == 0)
{
return NO; // return NO to not change text
}
else
{return YES;}
}

How do I identify or know which control is being referenced in a method?

In my specific case, how do I identify or know which UITextField is being referenced in shouldChangeCharactersInRange method?
I know the parameter (UITextField*)textField contains the object being referenced, but how do I compare to identify which one it is?
If you create your interface using IB then you can create IBOutlet in your controller for each UI element, connect then in IB and later compare textField parameters with them:
//header
IBOutlet UITextField* nameField;
IBOutlet UITextField* addressField;
//Implementation
...
if (textField == nameField){
}
if (textField == addressField){
}
2 In IB you can also assign a unique tag value for each UITextField (available for each UIView subclasses) and compare tag values:
#define nameTag 10
#define addressTag 11
//Implementation
...
if (textField.tag == nameTag){
}
if (textField.tag == addressTag){
}
The most elegant solution is to use tags from interface builder / storyboard, assign tags for each of the text fields.
Then use a switch(textfield.tag) case in your code, code looks much cleaner compared to putting a lot of if statements

checking which UITextField is triggering textFieldShouldBeginEditing call

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