View Controller 中的两个 TextField 设置为委托,导致应用崩溃,NSRange、范围或索引越界

Posted

技术标签:

【中文标题】View Controller 中的两个 TextField 设置为委托,导致应用崩溃,NSRange、范围或索引越界【英文标题】:Two TextFields in a View Controller set as the delegate, causing the app to crash with NSRange, range or index out of bounds 【发布时间】:2013-12-05 14:47:32 【问题描述】:

我有一个视图控制器,令人讨厌地不断崩溃。文本字段有 3 个文本字段(名称、项目、标题),在我尝试引入 UITextFieldDelegate 方法之前一切正常。

- (BOOL)textFieldShouldReturn:(UITextField *)textField

    [textField resignFirstResponder];

    return YES;

当我这样做并在 viewDidLoad 中,将 nameTextField 以及 itemTextField 和 titleTextField 设置为委托时,当我运行应用程序并在 itemText/titleTextField 中键入几个字符时,它会导致程序崩溃并出现以下错误:

Terminating app due to uncaught exception 'NSRangeException', reason: '-[__NSCFString replaceCharactersInRange:withString:]: Range or index out of bounds'

如果我只是删除self.itemTextField.delegate = self,当我在该字段中键入时它不会使应用程序崩溃,titleTextField 也是如此。

为了强调这一点,设置为委托的 nameTextField 将继续工作而不会崩溃。但是,似乎添加另一个 textField 作为委托也会导致此处崩溃。

我有以下两种方法可以帮助我在 nameTextField 下提供一个自动完成的表格视图,因此当用户输入时,他们可以引用以前输入的名称(存储在 Core Data 等中)。

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string

        self.autoCompleteTableView.hidden = NO;
        self.substring = [NSString stringWithString:self.nameTextField.text];
        self.substring = [self.substring stringByReplacingCharactersInRange:range withString:string];
        NSLog(@"Value of entered string = %@", self.substring);
        [self searchAutocompleteEntriesWithSubstring:self.substring];

        return YES;

调用者:

- (void)searchAutocompleteEntriesWithSubstring:(NSString *)substring 

    self.autocompleteFetchedResultsController = nil;
    [self autocompleteFetchedResultsController];
    NSLog(@"Table = %@", self.autoCompleteTableView);

    [self.autoCompleteTableView reloadData];

我知道有大量与此错误相关的问题和博客文章,但我不确定如何解决此问题。

我在尝试实现上述 UITextFieldDelegate 方法时注意到崩溃,并且我看到 viewDidLoad 中的 self.titleTextField.delegate = self 足以导致崩溃。 self.nameTextField.delegate = self 已设置,并且无论 titleTextField 和 itemTextField 是什么都有效。

任何对此的解释将不胜感激! 谢谢,

【问题讨论】:

【参考方案1】:

问题发生在下面的这个方法中,你有 3 个文本字段,它们都调用了这个方法,但你假设这只是发生在 self.nameTextField:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string

        self.autoCompleteTableView.hidden = NO;
        self.substring = [NSString stringWithString:self.nameTextField.text];
        self.substring = [self.substring stringByReplacingCharactersInRange:range withString:string];
        NSLog(@"Value of entered string = %@", self.substring);
        [self searchAutocompleteEntriesWithSubstring:self.substring];

        return YES;

您可以通过多种方式修复它,这取决于您的要求,其中之一是比较编辑的文本字段是您的 self.nameTextField,但我不知道您想要实现什么:

 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
    
        if (self.nameTextField == textField)
        
            self.autoCompleteTableView.hidden = NO;
            self.substring = [NSString stringWithString:self.nameTextField.text];
            self.substring = [self.substring stringByReplacingCharactersInRange:range withString:string];
            NSLog(@"Value of entered string = %@", self.substring);
            [self searchAutocompleteEntriesWithSubstring:self.substring];
        
            return YES;
    

【讨论】:

HI @Greg - 非常感谢您的回复 - 修复了它 - 这是所需的 if 语句。非常感谢mch!我正在尝试在 textFields 下方设置一个自动完成表格视图,以填充您之前输入的条目 - 将为此提出另一个问题 - 再次感谢!这就像一个魅力! :)【参考方案2】:

shouldChangeCharactersInRange: 中的 NSLog 语句移动到该函数的第一行,您就会知道发生了什么。

提示:您的代表会从不同的 TextField 中调用...

【讨论】:

【参考方案3】:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range 内将self.nameTextField 更改为textField

您应该使用调用委托的 textField,而不是可能与用户正在修改的 textField 不同的类成员

【讨论】:

感谢 Slecome - 这非常有帮助。那和格雷格的回答让这对我有用。再次感谢

以上是关于View Controller 中的两个 TextField 设置为委托,导致应用崩溃,NSRange、范围或索引越界的主要内容,如果未能解决你的问题,请参考以下文章

Xcode View Controller - 水平方向问题

SpringMVC中的mvc:view-controller标签

将 jQuery 数据从 View 传递到 Controller 并将其保存为多对多

Activity View Controller 在新行中显示 URL

我用Xcode创建了两个view controller,在第二个viewcontroller中添加按钮之后,怎么进行代码关联?

将数据从 Table View Cell 传递到 IOS 中的 View Controller