之前在折腾:
iOS中,将Table View的Table View Cell中的TextField换为下拉菜单
过程中,已经实现了基本的UIPickerView的显示和控制了,但是还要实现不能同时显示UIPickerView和键盘。
现在就继续折腾,如何实现此功能。
1. 想要去把BirdName的TextField的键盘禁止掉,但是没找到选项。
去把TextField的Content的Enable取消选择:
运行的结果是,鼠标的确无法选中BirdName的TextField了:
对应的,也没了键盘弹出来了。所以,也算基本实现了不弹出键盘的功能。
2.接下来就是去把这个UIPickerView变成动态的,当选中第一行BirdName时,再显示UIPickerView,选择的非第一行,则隐藏UIPickerView。
3.试着把UIPickerView的hidden选上,让其初始化就隐藏掉,然后再去写代码,当选到第一行时,再显示出来。
然后看到原先代码中就已经有了那个didSelectRowAtIndexPath,所以,应该是去实现对应的代码,检测是选择了第一个行,然后显示对应的UIPickerView。
然后对于如何获得选中的UITableViewCell的话,从:
UITableViewDelegate Protocol Reference
想到了去查其所属的UITableView
,然后在其中,找到了“Managing Selections”部分中的
可以获得对应选中的cell的index,然后通过index,去调用“Accessing Cells and Sections”中的
就可以获得对应的cell了。
而且,参考:如何得到自定义UITableViewCell中的按钮所在的cell的indexPath.row,也想起了,之前的DateCell中,也是有对应的用法的:
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow]; UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
所以,就去写出了对应代码:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { // Navigation logic may go here. Create and push another view controller. /* <#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:@"<#Nib name#>" bundle:nil]; // ... // Pass the selected object to the new view controller. [self.navigationController pushViewController:detailViewController animated:YES]; */ UITableViewCell *selectedCell = [self.addSightingTableView cellForRowAtIndexPath:indexPath]; if([selectedCell.reuseIdentifier isEqualToString: @"BirdNameCell"]){ self.birdNamePickerView.hidden = FALSE; } else{ self.birdNamePickerView.hidden = TRUE; } }
运行结果,可以实现,点击第一行,显示对应的UIPickerView,点击第二行,UIPickerView消失:
不过,这样还是有个缺点,那就是,点击第一行时,显示了UIPickerView后,再点击第二行Location中的TextField,结果UIPickerView没有消失,同时又显示出来了键盘:
所以,还是需要去优化代码。
4.上述参考UITableViewDelegate Protocol Reference时,看到在
– tableView:didSelectRowAtIndexPath:
旁边还有其他几
– tableView:willSelectRowAtIndexPath:
– tableView:willDeselectRowAtIndexPath:
– tableView:didDeselectRowAtIndexPath:
看了下函数解释,很明显,可以实现对应的didDeselectRowAtIndexPath去实现,取消选择第一行时,将对应的UIPickerView隐藏掉,
同时,上面代码中的hidden=TRUE也可以去掉了。
所以,修正后的代码为:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { // Navigation logic may go here. Create and push another view controller. /* <#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:@"<#Nib name#>" bundle:nil]; // ... // Pass the selected object to the new view controller. [self.navigationController pushViewController:detailViewController animated:YES]; */ UITableViewCell *selectedCell = [self.addSightingTableView cellForRowAtIndexPath:indexPath]; if([selectedCell.reuseIdentifier isEqualToString: @"BirdNameCell"]){ self.birdNamePickerView.hidden = FALSE; } } -(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath{ UITableViewCell *deSelectedCell = [self.addSightingTableView cellForRowAtIndexPath:indexPath]; if([deSelectedCell.reuseIdentifier isEqualToString: @"BirdNameCell"]){ self.birdNamePickerView.hidden = TRUE; } }
结果却是问题依旧,和之前的现象一样,点击Location的TextField,此时并没有取消选择第一行,所以还是出现UIPickerView和键盘并存的问题。
5.后来想到之前别人所说的,对于刚点击TextField时,对应有个函数是textFieldShouldBeginEditing,所以官网中去搜了下,找到textFieldShouldBeginEditing的解释,可以把代码加入到此处试试。
然后就想要去实现对应函数,对应的.h中已经添加了对于UITextFieldDelegate的支持了:
@interface AddSightingViewController : UITableViewController <UITextFieldDelegate, UIPickerViewDataSource, UIPickerViewDelegate> { NSArray *birdNameList; }
然后去写代码时,先写了#pragma,然后再去写-(void),结果动态匹配的函数中,却没有我想要的textFieldShouldBeginEditing,而只有textFieldShouldEndEditing:
觉得很是诡异,不知道哪里格式写错了。
后来才注意到,原来textFieldShouldBeginEditing的函数原型是:
– (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
而此处开头写的void不匹配,所以当前没有显示出来textFieldShouldBeginEditing了。
不过,对于此处需要实现的功能,当将要或已经开始编辑的时候,就隐藏UIPickerView,倒也是无所谓,用哪个都可以。
所以代码如下:
#pragma mark TextField Delegate -(void)textFieldDidBeginEditing:(UITextField *)textField{ self.birdNamePickerView.hidden = TRUE; }
然后运行结果就是所希望的了:
即,当点击第一行的BirdName时,UIPickerView可以显示,当取消选择BirdName行,则UIPickerView可以隐藏;
同时如果是从BirdName直接切换到Location的TextField时,也可以隐藏UIPickerView然后显示对应的键盘。
6.截止目前,基本的功能,都已经实现了。
不过现在还是有个小问题,当在Location的TextField中,没有点击虚拟键盘上的Done按键的话,此时键盘就还是存在的,所以此时如果切换到第一行,则又会出现UIPickerView和键盘同时出现的问题:
所以,还是需要去解决。后来想的办法是,参考之前的如何让TextField消失的办法,即取消第一响应,所以在didSelectRowAtIndexPath中的if([selectedCell.reuseIdentifier isEqualToString: @"BirdNameCell"])中添加对应的代码,变成:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { // Navigation logic may go here. Create and push another view controller. /* <#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:@"<#Nib name#>" bundle:nil]; // ... // Pass the selected object to the new view controller. [self.navigationController pushViewController:detailViewController animated:YES]; */ UITableViewCell *selectedCell = [self.addSightingTableView cellForRowAtIndexPath:indexPath]; if([selectedCell.reuseIdentifier isEqualToString: @"BirdNameCell"]){ self.birdNamePickerView.hidden = FALSE; [self.locationInput resignFirstResponder]; } }
即可解决两者同时出现的问题了:
保证了同时只出现一个,键盘或者是UIPickerView。
后续总结参见:iOS中,将Table View的Table View Cell中的TextField换为下拉菜单
转载请注明:在路上 » 【已解决】如何实现在UITableView中,同时只显示UIPickerView和键盘中的某一个,而不允许同时显示