Adding a method to my uitextfield in a cell?

I am adding this method to my code to format a text field. I use the code below to try and add a method, but it does not work, what am I doing wrong?

.h file

NSString* phone_; UITextField* phoneFieldTextField; @property (nonatomic,copy) NSString* phone; 

.m file

 @synthesize phone = phone_; ViewDidLoad{ self.phone = @""; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil]; // Make cell unselectable and set font. cell.selectionStyle = UITableViewCellSelectionStyleNone; cell.textLabel.font = [UIFont fontWithName:@"ArialMT" size:13]; if (indexPath.section == 0) { UITextField* tf = nil; switch ( indexPath.row ) { case 3: { cell.textLabel.text = @"Phone" ; tf = phoneFieldTextField = [self makeTextField:self.phone placeholder:@"xxx-xxx-xxxx"]; phoneFieldTextField.keyboardType = UIKeyboardTypePhonePad; [self formatPhoneNumber:phoneFieldTextField.text deleteLastChar:YES]; [cell addSubview:phoneFieldTextField]; break ; } // Textfield dimensions tf.frame = CGRectMake(120, 12, 170, 30); // Workaround to dismiss keyboard when Done/Return is tapped [tf addTarget:self action:@selector(textFieldFinished:) forControlEvents:UIControlEventEditingDidEndOnExit]; } } // Textfield value changed, store the new value. - (void)textFieldDidEndEditing:(UITextField *)textField { //Section 1. if ( textField == nameFieldTextField ) { self.name = textField.text ; } else if ( textField == addressFieldTextField ) { self.address = textField.text ; } else if ( textField == emailFieldTextField ) { self.email = textField.text ; } else if ( textField == phoneFieldTextField ) { self.phone = textField.text ; }else if ( textField == dateOfBirthTextField ) { self.dateOfBirth = textField.text ; } } - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { NSString* totalString = [NSString stringWithFormat:@"%@%@",textField.text,string]; // if it the phone number textfield format it. if(textField.tag == 10 ) { if (range.length == 1) { // Delete button was hit.. so tell the method to delete the last char. textField.text = [self formatPhoneNumber:totalString deleteLastChar:YES]; } else { textField.text = [self formatPhoneNumber:totalString deleteLastChar:NO ]; } return false; } return YES; NSLog(@"Testing should change character in range"); } -(NSString*) formatPhoneNumber:(NSString*) simpleNumber deleteLastChar:(BOOL)deleteLastChar { if(simpleNumber.length == 0) return @""; // use regex to remove non-digits(including spaces) so we are left with just the numbers NSError *error = NULL; NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"[\\s-\\(\\)]" options:NSRegularExpressionCaseInsensitive error:&error]; simpleNumber = [regex stringByReplacingMatchesInString:simpleNumber options:0 range:NSMakeRange(0, [simpleNumber length]) withTemplate:@""]; // check if the number is to long if(simpleNumber.length>10) { // remove last extra chars. simpleNumber = [simpleNumber substringToIndex:10]; } if(deleteLastChar) { // should we delete the last digit? simpleNumber = [simpleNumber substringToIndex:[simpleNumber length] - 1]; } // 123 456 7890 // format the number.. if it less then 7 digits.. then use this regex. if(simpleNumber.length<7) simpleNumber = [simpleNumber stringByReplacingOccurrencesOfString:@"(\\d{3})(\\d+)" withString:@"($1) $2" options:NSRegularExpressionSearch range:NSMakeRange(0, [simpleNumber length])]; else // else do this one.. simpleNumber = [simpleNumber stringByReplacingOccurrencesOfString:@"(\\d{3})(\\d{3})(\\d+)" withString:@"($1) $2-$3" options:NSRegularExpressionSearch range:NSMakeRange(0, [simpleNumber length])]; if (simpleNumber.length == 10 && deleteLastChar == NO) { [self resignFirstResponder];} return simpleNumber; NSLog(@"Testing format phone number"); } #pragma mark - TextField -(UITextField*) makeTextField: (NSString*)text placeholder: (NSString*)placeholder { UITextField *tf = [[UITextField alloc] init]; tf.placeholder = placeholder; tf.text = text ; tf.autocorrectionType = UITextAutocorrectionTypeNo ; tf.autocapitalizationType = UITextAutocapitalizationTypeNone; tf.adjustsFontSizeToFitWidth = YES; tf.returnKeyType = UIReturnKeyDone; tf.textColor = [UIColor colorWithRed:56.0f/255.0f green:84.0f/255.0f blue:135.0f/255.0f alpha:1.0f]; return tf ; } 
+6
source share
4 answers

Method used:

 -(NSString*) formatPhoneNumber:(NSString*) simpleNumber deleteLastChar:(BOOL)deleteLastChar 

Returns an NSString object. In your case, you are calling the method correctly, but you are not setting the Returned NSString object to anything. He just hangs there. You must set the PhoneTextField to formatted text as follows:

 phoneFieldTextField.text = [self formatPhoneNumber:phoneFieldTextField.text deleteLastChar:YES]; 

NOTE. If you want to know more about return methods, read the following:

If you notice that most methods are of type void . You know this when you see a method like this:

 - (void)someMethod { int x = 10; } 

Which means emptiness, that someMethod returns nothing to you. It just executes the code inside the method. Now, methods than returning an object or some other data type look like this:

 - (int)returnSomething { int x = 10; return x; } 

The first thing you notice is the return type, which is no longer invalid, is int. This means that the method will return an integer type. In this case, the code is executed, and you return the value of x.

This is only the beginning of the topic of return methods, but hopefully this will make it a little easier for you.

+8
source

First you need to tell us What does not work, we do not have your application and all your code. You need to explain what works and what does not work. It took more time to understand that your question is why textField:shouldChangeCharactersInRange: does not work. You set a breakpoint in the function to see what it does. Was this caused?

However, your mistake is that textField:shouldChangeCharactersInRange: uses tags to identify text fields, and the rest of the code uses pointers

 // if it the phone number textfield format it. - if(textField.tag == 10 ) { + if(textField.tag == phoneFieldTextField ) { 

Also, you did not specify the code for makeTextField:placeholder: It may have problems. Compare your code with makeTextField:placeholder: in my example.

I created a sample project on GitHub. To fix it. I also demonstrate a better approach to creating input forms using table views.

https://github.com/GayleDDS/TestTableViewTextField.git

Take a look at diffs to see what I did for YourTableViewController.m so that everything works.

https://github.com/GayleDDS/TestTableViewTextField/commit/d65a288cb4da7e1e5b05790ea23d72d472564793 https://github.com/GayleDDS/TestTableViewTextField/commit/31ecaec8c9c01204645d72

There are several other issues here:

  • You need to call [super viewDidLoad]; in your viewDidLoad method
  • You need to properly defer your code (there may be a problem with cutting and pasting)
  • You must use the storyboard to create your presentations. See the Better Solution Tab and BetterTableViewController Implementation.

Must Watch - iOS Development Video

+3
source

It looks like you are not setting the <UITextFieldDelegate> delegate in the .h file and you are not setting the delegate property to textfield self tf.delegate = self; to call - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string

Try it and let me know how this happens.

-Good luck!

+1
source

@koray was right: you need to set up a delegate for the class. Your class should be declared as an implementation of the UITextFieldDelegate protocol (in addition to the UITableViewDataSource, I suppose)

then in your method makeTextField: (NSString *) text: (NSString *) placeholder you should have something like:

 -(UITextField*) makeTextField: (NSString*)text placeholder: (NSString*)placeholder { UITextField *tf = [[UITextField alloc] initWithFrame:CGRectMake(40, 0, 150, 40)]; tf.placeholder = placeholder; // (...) tf.delegate = self; return tf ; } 

Then you need to properly configure the delegate methods. In the following example, I have a navigation bar, since the numeric panel does not have a return or end button. I am setting up a button that will act like a button made (you may have another way to make a keyboard, and switching between text fields will complete the release):

 - (void) textFieldDidBeginEditing:(UITextField *)textField { UIBarButtonItem *doneBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(doneEditing:)]; self.navBar.topItem.rightBarButtonItem = doneBtn; } - (void) doneEditing:(id) sender { if(phoneFieldTextField.isFirstResponder) { [phoneFieldTextField resignFirstResponder]; } // (...) self.navBar.topItem.rightBarButtonItem = nil; } 

Then the magic happens in the delegate method textDidEndEditing:

 - (void)textFieldDidEndEditing:(UITextField *)textField { if ( textField == phoneFieldTextField ) { self.phone = [self formatPhoneNumber:textField.text deleteLastChar:YES] ; // convert [phoneFieldTextField setText:self.phone]; // display } // (...) } 
+1
source

Source: https://habr.com/ru/post/945086/


All Articles