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中添加按钮之后,怎么进行代码关联?