隐藏以编程方式创建的自动完成 UITableView
Posted
技术标签:
【中文标题】隐藏以编程方式创建的自动完成 UITableView【英文标题】:Hiding an autocomplete UITableView that was created programmatically 【发布时间】:2014-01-14 19:04:20 【问题描述】:我正在使用 tutorial 的自动完成 UITableView 构建一个应用程序。我的自动完成功能正常工作,但我希望 UITableView-autocomplete 下拉菜单在单击该单词或在外部触摸它时消失。当以编程方式设置对象时,我不确定如何设置委托。我只使用界面生成器完成了这项工作。
.h
@interface slrpViewController : UIViewController<UITextFieldDelegate, UIPickerViewDelegate, UIPickerViewDataSource>
NSMutableArray *dataArray;
NSMutableData *receivedData;
NSMutableArray *pastUrls;
NSMutableArray *autocompleteUrls;
UITableView *autocompleteTableView;
@property(nonatomic, retain) IBOutlet UITextField *eWordEntered;
@property (nonatomic, retain) NSMutableArray *pastUrls;
@property (nonatomic, retain) NSMutableArray *autocompleteUrls;
@property (retain, nonatomic) NSMutableData *responseData;
@property (nonatomic, retain) UITableView *autocompleteTableView;
-(void)setReceivedData:(NSMutableData*)pReceivedData;
-(NSMutableData *) getReceivedData;
-(void) getAutoCompleteArray;
-(void)searchAutocompleteEntriesWithSubstring:(NSString *)substring;
.m
- (void)viewDidLoad
[super viewDidLoad];
[self getAutoCompleteArray];
pastUrls = [[NSMutableArray alloc] init];
NSLog(@"In the viewDidLoad and pasturl is: %@", self.pastUrls);
self.autocompleteUrls = [[NSMutableArray alloc] init];
autocompleteTableView = [[UITableView alloc] initWithFrame:CGRectMake(210, 225, 310, 120) style:UITableViewStylePlain];
self.autocompleteTableView.delegate = self;
self.autocompleteTableView.dataSource = self;
autocompleteTableView.scrollEnabled = YES;
autocompleteTableView.hidden = YES;
[self.view addSubview:autocompleteTableView];
-(void)setReceivedData:(NSMutableData*)pReceivedData
receivedData = pReceivedData;
-(NSMutableData *) getReceivedData
return receivedData;
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
[receivedData setLength:0];
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
[receivedData appendData:data];
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
NSError *e = nil;
NSError *error = nil;
NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData: receivedData options: NSJSONReadingMutableContainers error: &e];
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:receivedData
options:kNilOptions
error:&error];
seneca_word.ids = [jsonDict objectForKey:@"ids"];
NSArray *array_ids = [jsonDict objectForKey:@"ids"];
NSString *ids = array_ids[0];
seneca_word.ids = ids;
for (id key in jsonDict)
NSLog(@"key: %@, value: %@", key, [jsonDict objectForKey:key]);
NSLog(@"The value of bases by itself is: %@", [jsonDict objectForKey:@"bases"]);
if (!jsonArray)
NSLog(@"Error parsing JSON: %@", e);
else
if([jsonDict objectForKey:@"english"] != nil)
pastUrls = [jsonDict objectForKey:@"bases"];
else
//Some of JSON object that I don't want to use here
//else
//(void)connectionDidFinishLoading
- (void)searchAutocompleteEntriesWithSubstring:(NSString *)substring
[autocompleteUrls removeAllObjects];
for(NSString *curString in pastUrls)
NSRange substringRange = [curString rangeOfString:substring];
if (substringRange.location == 0)
[autocompleteUrls addObject:curString];
[autocompleteTableView reloadData];
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
autocompleteTableView.hidden = NO;
NSString *substring = [NSString stringWithString:textField.text];
substring = [substring stringByReplacingCharactersInRange:range withString:string];
[self searchAutocompleteEntriesWithSubstring:substring];
return YES;
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger) section
return autocompleteUrls.count;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
UITableViewCell *cell = nil;
static NSString *AutoCompleteRowIdentifier = @"AutoCompleteRowIdentifier";
cell = [tableView dequeueReusableCellWithIdentifier:AutoCompleteRowIdentifier];
if (cell == nil)
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:AutoCompleteRowIdentifier];
cell.textLabel.text = [autocompleteUrls objectAtIndex:indexPath.row];
return cell;
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
self.eWordEntered.text = selectedCell.textLabel.text;
if(tableView == autocompleteTableView)
//The autocomplete table view is the one that fired the didSelect delegate method
//So hide the autocomplete table.
//do whatever else you need to do to empty the autocompleteTableView's data source
//or/and simply hide the table after that
[autocompleteTableView setHidden:YES];
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
//When the user clicks outside of the uitableview it will disappear
[autocompleteTableView setHidden:YES];
如您所见,我使用从 RESTful API 获得的 JSON 数据填充了自动完成 UITableView。
我收到了警告,Assigning to 'id<UITableViewDelegate>' from incompatible type 'ViewController *const __strong'
的行:
self.autocompleteTableView.delegate = self;
self.autocompleteTableView.dataSource = self;
我想,一旦我把代表的东西整理好,我就可以做我想做的事了。我做了一些研究并尝试创建一个委托类,但无法使该解决方案发挥作用。我什至不确定这是否是解决此问题的正确方法,因为我通常通过界面构建器而不是以编程方式来做这些事情。非常感谢任何方向或帮助。谢谢!
【问题讨论】:
【参考方案1】:您应该使用 tableView 的 didSelectCellAtIndexPathRow
委托方法来识别用户对来自 tableView 的单元格的点击。如果您以编程方式创建 tableView 就可以了。
只需确保 UIViewController 符合 UITableViewDelegate
和 UITableViewDataSource 协议即可。
确保将 tableView 的 delegate 和 dataSource 属性设置为 self。
在 viewController 的 .m
文件中实现 didSelectCellAtIndexPathRow
委托方法,如下所示:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
然后在该委托方法中,您需要帮助检测您的 didSelect 方法是从哪个 tableView 触发的,因为您只想在用户从该表中选择一个单元格时隐藏自动完成表。因此,您可以像这样进行简单的 tableView 检查:
if(tableView == autocompleteTableView)
//The autocomplete table view is the one that fired the didSelect delegate method
//So hide the autocomplete table.
//do whatever else you need to do to empty the autocompleteTableView's data source
//or/and simply hide the table after that
[autocompleteTableView setHidden:YES];
您可能还想确保在用户在文本字段中输入内容时将 autocompleteTableView
隐藏属性设置为 NO
,以便自动完成可以再次显示。
这就是朋友。
【讨论】:
谢谢!我更新了代码/问题以反映 3、4、5。当用户单击其中一个选项时,uitableview-autocomplete 现在确实会成功消失。我喜欢它现在在用户输入时“刷新”的方式。如果用户在 uitableview 之外单击,有没有办法让 uitableview 消失?就像 uitableview 和 viewcontroller 之外的任何地方一样?不确定这是否应该是单独的问题,但我想我会问。 您也可以在 touchesBegan 中执行相同的操作。我建议您对 touchesBegan 方法进行一些研究,该方法将检测屏幕上任何位置的触摸,如果尚未隐藏,您可以再次将 autoCompleteTableView 的 hidden 属性设置为 YES。【参考方案2】:尝试设置 self.autocompleteTableView.hidden = YES;
【讨论】:
以上是关于隐藏以编程方式创建的自动完成 UITableView的主要内容,如果未能解决你的问题,请参考以下文章