TextField作为搜索栏触发Range崩溃及大小写不兼容问题求助
解决TextField搜索栏的Range崩溃与大小写敏感问题
我来帮你搞定这两个头疼的问题——输入时的Range崩溃和大小写敏感的搜索,先一步步拆解根源再给你修正后的代码:
一、Range崩溃的常见原因与修复
你的崩溃大概率出自这几个场景:
searchArray没提前初始化,导致过滤时调用数组方法直接报错- 处理搜索文本时没判断空字符串情况,
rangeOfString:在空文本下返回的Range可能触发异常 - UITableView数据源方法里没正确区分
isFilter状态,误用数组导致越界
修复要点:
- 在
viewDidLoad里提前初始化searchArray,避免空指针 - 搜索前先判断文本是否为空,空文本直接重置为原数组状态
- 使用
rangeOfString:后,必须判断返回的range.location不等于NSNotFound,确保是有效匹配
二、大小写敏感问题的修复
默认的rangeOfString:是区分大小写的,只需要给它加上NSCaseInsensitiveSearch选项,就能轻松实现忽略大小写的搜索匹配。
修正后的完整代码
#import "ViewController.h" #import "AFNetworking.h" #import <QuartzCore/QuartzCore.h> @interface ViewController () <UITextFieldDelegate, UITableViewDataSource, UITableViewDelegate> { NSMutableArray *countryArray; NSMutableArray *searchArray; NSString *searchTextString; BOOL isFilter; } // 假设你有对应的UI控件IBOutlet,自行关联 @property (nonatomic, weak) IBOutlet UITextField *searchTextField; @property (nonatomic, weak) IBOutlet UITableView *tableView; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // 提前初始化数组,避免空指针异常 countryArray = [NSMutableArray array]; searchArray = [NSMutableArray array]; // 这里放你加载countryArray数据的逻辑(比如网络请求或本地读取) // [self loadCountryData]; // 设置代理 self.searchTextField.delegate = self; self.tableView.dataSource = self; self.tableView.delegate = self; } // 监听TextField内容变化,执行搜索逻辑 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { searchTextString = [textField.text stringByReplacingCharactersInRange:range withString:string]; // 空文本时直接显示原数组 if ([searchTextString isEqualToString:@""]) { isFilter = NO; [self.tableView reloadData]; return YES; } isFilter = YES; [searchArray removeAllObjects]; for (NSString *country in countryArray) { // 忽略大小写匹配,同时判断是否为有效匹配 NSRange resultRange = [country rangeOfString:searchTextString options:NSCaseInsensitiveSearch]; if (resultRange.location != NSNotFound) { [searchArray addObject:country]; } } [self.tableView reloadData]; return YES; } // 点击TextField清除按钮时重置状态 - (BOOL)textFieldShouldClear:(UITextField *)textField { isFilter = NO; [self.tableView reloadData]; return YES; } // UITableView数据源方法 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return isFilter ? searchArray.count : countryArray.count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *cellID = @"CountryCell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID]; if (!cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID]; } NSString *countryName = isFilter ? searchArray[indexPath.row] : countryArray[indexPath.row]; cell.textLabel.text = countryName; return cell; } @end
额外提醒
- 确保你的
countryArray已经正确加载了数据,不然会出现无内容显示的情况 - 如果搜索数据量较大,建议把搜索逻辑放到GCD异步线程里,避免主线程卡顿(简单场景下主线程也完全够用)
内容的提问来源于stack exchange,提问作者kirao leo
相关产品推荐
相关产品推荐

