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

给Your Second iOS App的BirdWatching从文本输入框TextField变成换为下拉菜单UIPickerView

iOS crifan 3695浏览 0评论

之前已实现了添加Clear button,现在根据Your Second iOS App – Next Steps的建议,将Bird Name的TextField换为下拉菜单:


1.网上找了下"iOS 下拉菜单",竟然没有找到有效的帖子。很是无语。

2.自己手动从Object中找到一个貌似的控件 pick view:

found picker view

但是后来从:

tableviewcell中添加一个自定义下拉菜单控件无法正常使用的问题

得知了原来这个东西叫做 drop down,然后google就可以搜到:

iPhone/iPad UI: seeking drop-down control

其中说到,默认的pick view不好用,希望找到好用的。

但是看了问题回答者给出的链接,除了有个可以找到教程的,其他的解释,也不是很详细啊。

3.算了,还是先自己去折腾折腾吧。

先是拖进来再说:

added picker view

但是却还是不会使用。

4.然后去参考相关的LocateMe的示例代码,也看不太懂。

5.搜到了一些教程:

An iOS 5 iPhone UIPickerView Example

UIPickerView Example

UIPickerView – Creating a simple picker view

 

打算去参考参考的,结果却发现,现在最需要学习的,其实是整套MVC的逻辑,具体是如何应用到设计过程中的。

即,拖动了一个Picker View控件后,这个是View,余下的Model和Controller的机制,是如何实现的。

6.看了N多帖子后,多delegate和protocol等有了稍微进一步的了解了。

但是现在的情况是,已经参考:

An iOS 5 iPhone UIPickerView Example

实现了其中UIPickerViewDataSourcenumberOfComponentsInPickerView:pickerView:numberOfRowsInComponent:了,但是结果Picker View还是不显示。

7.后来想到,好像是由于还没有实现UIPickerViewDelegate的函数和剩下的。

然后又去实现:pickerView:titleForRow:forComponent:

– pickerView:didSelectRow:inComponent:

但是结果还是不能显示。

8.参考:

UIPickerView添加后不显示问题(Outlets DataSource和delegate不知道怎么连)

去viewDidLoad中添加了:

self.birdNameChoosed.delegate = self;

然后最后终于显示picker view了:

in end show picker view

不过,此处关于如何实现”把delegate连去viewControllers“,尝试了下,

storyboard中右击picker view后,可以看到delegate,点击加号,但是却链接不上我的AddSightingViewController.m(和AddSightingViewController.h):

can not link delegate

所以感觉还不是很正常啊。

后来才搞懂,原来是链接到下面的那个黄色圆图标:

link to Add Sighting View Controller

但是好像代码中,没有在viewDidLoad中添加代码啊。

不过运行时是正常的,可以显示picker view。

但是,却又出现了只能显示但无法选择/选中的问题了。

详细折腾过程参见:

【已解决】UIPickerView无法/不能选择/选中

9.解决了UIPickerView选择的问题,接着就是去实现,点击BirdName和Location对应的TextField,分别显示UIPickerView和键盘,详情参考:

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

10.至此,算是基本完整这个基本的功能了。

总结目前功能为:

(1)对于BirdName 可以让用于从UIPickerView中选择,而无需手动输入;暂时也不支持手动输入;

(2)对于Location,需要用户手动输入,会显示出对应的键盘;

(3)在两者之间切换时,自动显示和隐藏对应的UIPickerView和键盘。

(4)保证了键盘和UIPickerView不同时出现。

 

【总结】

1. 更加深刻的理解了delegate的机制:

说白了,就是MVC中的view,其本身只负责显示,所以不方便,(根据MVC模型的定义,View也不允许)去实现关于控制部分的逻辑,比如关于此处的UITextField中键盘的是显示还是消失等,内容是否允许输入等等,关于逻辑判断的工作。

所以,Mac中会设计对应的UITextFieldDelegate ,定义一些Protocol,然后你如果想要控制关于显示的部分,就要去实现对应的接口接口,比如

– textFieldShouldReturn:

决定是否返回。

决定在输入框 将要编辑/已开始编辑/将要结束编辑/已结束编辑 等时候,去做一些其他的工作,比如判断输入内容是否合法之类的工作。

如此,实现显示和逻辑控制之间的分离。

2.对于TextField输入框,不允许输入的话,可以将storyboard中的属性Enable取消选择即可。这样就无法点击输入了,也不会弹出对应的键盘了。

3.想要把UIPickerView隐藏不显示,可以直接点击storyboard中其属性值Hidden,或者代码中通过

birdNamePickerView.hidden = TRUE

来实现。

4.关于UITableView,有个UITableViewDelegate,其中有几个函数,是关于选择某个Cell前后时所调用的:

可以通过实现对应的函数,在

将要选中某行

已经选中某行

将要取消选中某行

已经取消选中某行

的时候,添加代码,做自己想要做的事情。

比如我这里的就是,在didSelectRowAtIndexPath时,将UIPickerView显示,在didDeselectRowAtIndexPath时,将其隐藏。

5.关于键盘的事情:

(1)对于可输入控件TextField来说,默认点击到TextField时,会自动调出对应的键盘的,因为其(输入字符之后的)变成"第一响应者"了

(2)而想要取消键盘的显示,则是取消掉TextField这个“第一响应者”,所以对应代码就是:

[xxxTextField resignFirstResponder];


(3)之前所见到的相关的代码:

- (BOOL)textFieldShouldReturn:(UITextField *)textField{
    if((textField == self.birdNameInput) || (textField == self.locationInput))
    {
        [textField resignFirstResponder];
    }

    return YES;
}

的含义就很清楚了:

A。首先是键盘上都有个对应的回车键Return Key

B。我们在Storyboard中把当前的TextField所关联的键盘的Return Key的文字显示设置为Done,所以键盘上显示的是Done按键

C。然后我们在TextField中输入完毕内容后,点击Done按键,然后对于此事件,会调用delegate函数textFieldShouldReturn,去问对应的delegate,然后此处函数中的实现是说,当此时的输入的TextField是我们之前自己的那两个birdNameInput和locationInput的话,那么就调用resignFirstResponder,取消该textField作为第一响应者,即,取消了键盘的显示了。


后续折腾参考:

给Your Second iOS App的BirdWatching中,添加自定义日期

转载请注明:在路上 » 给Your Second iOS App的BirdWatching从文本输入框TextField变成换为下拉菜单UIPickerView

发表我的评论
取消评论

表情

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

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

网友最新评论 (3)

    86 queries in 0.190 seconds, using 22.12MB memory