【问题标题】:UITextField shouldChangeCharactersInRange fires twice?UITextField shouldChangeCharactersInRange 触发两次?
【发布时间】:2015-09-14 14:45:37
【问题描述】:

我有一个表格视图。在cellForRowAtIndexPath 我有一个单元格,在那个单元格中有 UITextField。我这样设置文本字段的代表:cell.textField.delegate = self;。我需要在第三个字符上调用我的 API。因此,当用户在文本字段中键入 3 个字符时,会调用 API,因此会调用 shouldChangeCharactersInRange

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
   if (textField.text.length >= 2) {
     NSString *substring = [NSString stringWithString:textField.text];
     substring = [substring
                 stringByReplacingCharactersInRange:range withString:string];
    [API CALLED WITH BLOCK WITH TEXTFIELD TEXT AS PARAMETER:substring];
 }
  return YES;
}

问题是当我输入例如“abc”shouldChangeCharactersInRange 时第一次被调用并且参数是“abc”。其次,shouldChangeCharactersInRange 再次被调用,我的文本字段添加了另一个我没有输入的字符,它总是被复制的最后一个字符。所以在这个例子中,它发送“abcc”。你知道,有什么问题吗?

【问题讨论】:

  • 你说得对,就是这样。既有趣又奇怪

标签: ios objective-c uitextfield


【解决方案1】:

在该委托方法中设置断点有时会导致该方法被触发两次。尝试删除此处或您的 API 方法中遇到的所有断点,然后再次测试。


这可以很容易地复制。创建一个新项目,添加一个UITextField 插座并将代理设置为您的控制器。在控制器中实现textField:shouldChangeCharactersInRange: 并在NSLog 语句或其他东西上设置断点,以及return YES。有时,在告诉调试器继续之后,会生成第二次击键并再次击中您的委托方法。

【讨论】:

    【解决方案2】:

    我建议改用textFieldDidChange,因为这发生在输入文本之后,因此您不必处理附加字符串。从那里您可以检查 'text.lenght >=3' 来触发您的 API 调用。

    您可以像这样添加事件:

    [textField addTarget:self 
                  action:@selector(textFieldDidChange:) 
        forControlEvents:UIControlEventEditingChanged];
    

    编辑: 这段代码对我有用。我在单元班上派了代表。

    #import "AnotherTableViewCell.h"
    
    @implementation AnotherTableViewCell
    
    @synthesize myTextField = _myTextField;
    
    - (void)awakeFromNib {
        // Initialization code
    
        _myTextField.delegate=self;
    
        [_myTextField addTarget:self
                      action:@selector(textFieldDidChange:)
            forControlEvents:UIControlEventEditingChanged];
    }
    
    - (void)setSelected:(BOOL)selected animated:(BOOL)animated {
        [super setSelected:selected animated:animated];
    
        // Configure the view for the selected state
    }
    
    -(void)textFieldDidChange:(UITextField*)textField{
        if (textField.text.length>=3) {
            NSLog(@"Text >= 3: %@",textField.text);
        }
    }
    
    @end
    

    【讨论】:

    • 我试过了,和 shouldChangeCharactersInRange 一样。它会触发两次,复制最后一个字符。
    • 澄清一下,您是在单元格类或表格类中设置textfield 代表吗?
    • 任何一个地方都应该可以,我在这两个地方都测试过。 @rmaddy 发布的代码也可以。您可能需要检查其余代码。还要发布您的 API 调用的样子,问题可能就在那里。
    猜你喜欢
    • 1970-01-01
    • 2013-12-19
    • 1970-01-01
    • 2018-09-02
    • 1970-01-01
    • 1970-01-01
    • 2011-10-29
    • 1970-01-01
    • 2012-04-28
    相关资源
    最近更新 更多