最新消息:20210816 当前crifan.com域名已被污染,为防止失联,请关注(页面右下角的)公众号

【已解决】如何实现在UITableView中,同时只显示UIPickerView和键盘中的某一个,而不允许同时显示

iOS crifan 3575浏览 0评论

之前在折腾:

iOS中,将Table View的Table View Cell中的TextField换为下拉菜单

过程中,已经实现了基本的UIPickerView的显示和控制了,但是还要实现不能同时显示UIPickerView和键盘。

现在就继续折腾,如何实现此功能。


1. 想要去把BirdName的TextField的键盘禁止掉,但是没找到选项。

参考:如何设置点击Text Field不弹出键盘?

去把TextField的Content的Enable取消选择:

deselect content enable_thumb

运行的结果是,鼠标的确无法选中BirdName的TextField了:

cannot select textfiled_thumb

对应的,也没了键盘弹出来了。所以,也算基本实现了不弹出键盘的功能。

2.接下来就是去把这个UIPickerView变成动态的,当选中第一行BirdName时,再显示UIPickerView,选择的非第一行,则隐藏UIPickerView。

3.试着把UIPickerView的hidden选上,让其初始化就隐藏掉,然后再去写代码,当选到第一行时,再显示出来。

然后看到原先代码中就已经有了那个didSelectRowAtIndexPath,所以,应该是去实现对应的代码,检测是选择了第一个行,然后显示对应的UIPickerView。

然后对于如何获得选中的UITableViewCell的话,从:

UITableViewDelegate Protocol Reference

想到了去查其所属的UITableView,然后在其中,找到了“Managing Selections”部分中的

– indexPathForSelectedRow

可以获得对应选中的cell的index,然后通过index,去调用“Accessing Cells and Sections”中的

– cellForRowAtIndexPath:

就可以获得对应的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消失:

select 1st cell can show or hidden_thumb[1]

不过,这样还是有个缺点,那就是,点击第一行时,显示了UIPickerView后,再点击第二行Location中的TextField,结果UIPickerView没有消失,同时又显示出来了键盘:

pickerview and keyboard both show_thumb[1]

所以,还是需要去优化代码。

4.上述参考UITableViewDelegate Protocol Reference时,看到在

– tableView:didSelectRowAtIndexPath:

旁边还有其他几

看了下函数解释,很明显,可以实现对应的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:

no textFieldShouldBeginEditing_thumb

觉得很是诡异,不知道哪里格式写错了。

后来才注意到,原来textFieldShouldBeginEditing的函数原型是:

– (BOOL)textFieldShouldBeginEditing:(UITextField *)textField

而此处开头写的void不匹配,所以当前没有显示出来textFieldShouldBeginEditing了。

不过,对于此处需要实现的功能,当将要或已经开始编辑的时候,就隐藏UIPickerView,倒也是无所谓,用哪个都可以。

所以代码如下:

#pragma  mark TextField Delegate
-(void)textFieldDidBeginEditing:(UITextField *)textField{
    self.birdNamePickerView.hidden = TRUE;
}

然后运行结果就是所希望的了:

UIPickerView can hidden_thumb[1]

即,当点击第一行的BirdName时,UIPickerView可以显示,当取消选择BirdName行,则UIPickerView可以隐藏;

同时如果是从BirdName直接切换到Location的TextField时,也可以隐藏UIPickerView然后显示对应的键盘。

6.截止目前,基本的功能,都已经实现了。

不过现在还是有个小问题,当在Location的TextField中,没有点击虚拟键盘上的Done按键的话,此时键盘就还是存在的,所以此时如果切换到第一行,则又会出现UIPickerView和键盘同时出现的问题:

from location to birdname both show_thumb[1]

所以,还是需要去解决。后来想的办法是,参考之前的如何让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];
    }

}

即可解决两者同时出现的问题了:

only show one_thumb[1]

保证了同时只出现一个,键盘或者是UIPickerView。

 

后续总结参见:iOS中,将Table View的Table View Cell中的TextField换为下拉菜单

转载请注明:在路上 » 【已解决】如何实现在UITableView中,同时只显示UIPickerView和键盘中的某一个,而不允许同时显示

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

网友最新评论 (3)

  1. 群主,我蒙了,我不知道你的 UITableViewCell *selectedCell = [self.addSightingTableView cellForRowAtIndexPath:indexPath]是从哪里来的,能不能帮我解答一下?
    鄹小姐10年前 (2013-12-17)回复
    • 不好意思,真心记不清了。。。时间太久,忘了。。。
      crifan10年前 (2013-12-17)回复
88 queries in 0.184 seconds, using 22.22MB memory