向单元格中的 uitextfield 添加方法?

Posted

技术标签:

【中文标题】向单元格中的 uitextfield 添加方法?【英文标题】:Adding a method to my uitextfield in cell? 【发布时间】:2013-05-15 17:06:24 【问题描述】:

我将此Method 添加到我的代码中以格式化文本字段。我正在使用下面的代码尝试添加该方法,但它不起作用,我做错了什么?

.h 文件

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

.m 文件

@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's 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's less then 7 digits.. then use this regex.
if(simpleNumber.length<7)
    simpleNumber = [simpleNumber stringByReplacingOccurrencesOfString:@"(\\d3)(\\d+)"
                                                           withString:@"($1) $2"
                                                              options:NSRegularExpressionSearch
                                                                range:NSMakeRange(0, [simpleNumber length])];

else   // else do this one..
    simpleNumber = [simpleNumber stringByReplacingOccurrencesOfString:@"(\\d3)(\\d3)(\\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 ;

【问题讨论】:

【参考方案1】:

你使用的方法:

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

返回一个 NSString 对象。在您的情况下,您正在正确调用该方法,但您没有将 Returned NSString 对象设置为任何内容。它只是挂在那里。您需要将 phoneFieldTextField 设置为格式化文本,如下所示:

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

注意 - 如果您想了解有关返回方法的更多信息,请阅读以下内容:

如果您注意到大多数方法都是 void 类型。看到这样的方法就知道了:

- (void)someMethod 
    int x = 10;

void 的意思是 someMethod 不返回任何东西给你。它只是执行方法中的代码。现在,返回对象或其他数据类型的方法如下所示:

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

首先你会注意到返回类型不再是 void,它是一个 int。这意味着该方法将返回一个整数类型。在这种情况下,代码会执行并返回 x 的值。

这只是返回方法主题的开始,但希望它能让你更清楚。

【讨论】:

【参考方案2】:

首先,您需要告诉我们什么不起作用,我们没有您的应用和所有代码。你需要解释什么是有效的,什么是无效的。花了更长的时间才弄清楚您的问题是为什么 textField:shouldChangeCharactersInRange: 不起作用。您是否在函数中设置了断点以查看它在做什么。不是被调用了吗?

也就是说你的错误是textField:shouldChangeCharactersInRange: 使用标签来识别文本字段,但其余代码使用指针

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

另外,您没有包含makeTextField:placeholder: 的代码,其中也可能存在问题。将您的代码与我的示例中的 makeTextField:placeholder: 进行比较。

我在 GitHub 上创建了一个示例项目。要解决这个问题。我还演示了一种使用表格视图创建输入表单的更好方法。

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

查看两个差异,看看我对YourTableViewController.m 做了什么以使事情正常进行。

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

这里还有很多其他问题:

你需要调用[super viewDidLoad];在你的 viewDidLoad 方法中 您需要正确缩进代码(可能是剪切和粘贴问题) 您应该使用情节提要来创建视图。查看更好的解决方案选项卡和 BetterTableViewController 实现。

必看 - iOS 开发视频

WWDC 2011 - 会议 309 - 介绍 Interface Builder 故事板https://developer.apple.com/videos/wwdc/2011/?id=309

斯坦福 iPhone 编程课程(2013 年冬季) 一起编码:为 iPhone 和 iPad 开发应用程序https://itunes.apple.com/us/course/coding-together-developing/id593208016

Lecture 9. 滚动视图和表格视图 Lecture 16. Segues 和文本字段

【讨论】:

首先,我在标题中的问题确切地说明了什么不起作用。其次,“错误”不在textField:shouldChangeCharactersInRange: 中,因为它甚至不是我的方法,下面的 Dana 能够让它正常工作。我相应地设置了 textField.tag。我还记录了被调用的内容。我的案例 3 被调用得很好,一切都适用于单元格和占位符。 问题是格式化单元格以使用我在此站点上找到并正确引用的电话号码方法。 superView didLoad 也在我的viewDidLoad 中,这个问题不需要它。我也按照你的建议使用故事板。 嗨@Jason,您下载并签出我的示例应用了吗?好的,您设置了标签您是否还设置了委托?您是否还可以在上面的问题中包含您的 makeTextField 代码。谢谢 我没有设置委托,该死的。谢谢!!【参考方案3】:

看起来您没有在 .h 文件中设置委托 &lt;UITextFieldDelegate&gt;,也没有将文本字段的委托属性分配给自己 tf.delegate = self; 以便调用 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string

试试看,然后告诉我结果如何

-祝你好运!

【讨论】:

【参考方案4】:

@koray 是对的:您需要为班级设置委托。你的类应该被声明为实现协议 UITextFieldDelegate(除了 UITableViewDataSource,我假设)

然后在你的 makeTextField: (NSString*)text placeholder: (NSString*)placeholder 方法中,你需要有类似的东西:

-(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 ;

然后您需要正确设置委托方法。在下面的示例中,我有一个导航栏,因为数字键盘没有返回或完成按钮。我设置了一个按钮作为完成按钮(您可能有另一种方式使键盘运行,并且在文本字段之间切换无论如何都会触发编辑结束):

- (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;

然后,神奇的事情发生在 textDidEndEditing 委托方法中:

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

【讨论】:

以上是关于向单元格中的 uitextfield 添加方法?的主要内容,如果未能解决你的问题,请参考以下文章

UITableView 单元格中的 UITextField 以编程方式成为FirstResponder

自定义表格视图单元格中的 UITextField。点击单元格/文本字段时显示选择器视图

如何在可重用的 tableView 单元格中更新 UITextfield 中的文本值,每个单元格中的值不同

滚动 UITableView 框架问题以查看单元格中的 UITextField?

当点击自定义 TableView 单元格中的 UITextField 时转到新视图

将单元格中的 UITextField 文本保存到 NSUserDefaults 中?