注册 登录
主题 : UIPickerView的数据循环显示(老外的法子真BT)
级别: 精灵王

UID: 7927
精华: 1
发帖: 315
可可豆: 11333 CB
威望: 11633 点
在线时间: 1658(时)
注册时间: 2009-08-19
最后登录: 2018-11-05
0 楼:  发表于: 2010-07-23 08:49    发自: Web Page
来源于 iPhone类代码 分类

UIPickerView的数据循环显示(老外的法子真BT)    (在iOS代码库中浏览本帖)

原始链接:
http://www.timespace.org/2008/07/11/the-abusive-pickerview/

另外我想问个问题:
UIDatePicker里面的hour和min这两个字符串(数值大于1的情况下,会变成hours和mins),在UIPickerView上怎么表示出来?


THE ABUSIVE PICKERVIEW


iPhone SDK 2.0 is a welcome thing but some of the controls make you wonder how they are supposed to be easy to work with. One thing iPhone devs will need that has driven me nuts because so few implement it right yet in any of the apps I’ve seen it in. The odometer style pickerview, no one seems to understand so I’m going to break down the UIPickerView into its most basic components hopefully this helps someone with the spare time to develop for the iphone to create some kewl apps that use it to make the ui experience better.
First here is some sample code that should help you better understand how to virtually wrap the pickerview. What we have in the titleForRow method is an array the returns the value of the selected row modulus 10. This ensures we stay in our array and return the appropriate string label for the row we want. This means no matter what “row” the ui thinks we are in we will be returning what we want them to see for that row giving us the virtual wrap we want. The return could just as easily be simply the row%10 as an NSString without the array for a basic odometer style picker.


Some other code that helps us with the illusion is the numberOfRowsInComponent method. In here we return the number of possible rows to select. I started off using NSMaxIneger and quickly found this breaks everything so I bumped the number down until I got around 16384. This allows you to wrap around and around and force the user into having to be pretty dedicated to reach the end of the list breaking the illusion. Change the number down to 32 to see the end of the list and get a better feel for what is going on in the background as the delegate methods aid in rendering the UI.
Now what you really want to happen is if they hit the end of the list repopulate it and the easiest way to do this is redirect the list to its own middle. But if every time you did this you took them to the middle it would mess up their current selection so the algorithm has to be a little smarter and offset them to their current selection. There are three pieces to this. The first is the didSelectRow this delegate is called when the user stops moving the control. From here we want to call a delegate that is called when the control loads as well pickerViewLoaded. When the pickerViewLoaded delegate is called we setup the same max as the max returned in numberOfRowsInComponent because we want to go to the middle of the possible selections. We then take the max divided by two for the middle then use that value mod 10 to get the offset to take us to the nearest row divisible by ten. From here we can take the current selected row modulus ten and use that as the offset tot he current row we want them to be on. When we select this row without animation there should be no apparent movement to the end user and they should now be back towards the middle of the list.
The final piece of code here should enable us to return the number of horizontal components in the pickerview. As you can see the other methods have a component method that returns which column of data you are looking at. There is additional programming required for dealing with this but it shouldn’t be to difficult to figure out once you understand what you’re dealing with in the basics of the pickerview.
If your anything like me while the interface is unique but the loading mechanism I think could be significantly optimized but I think the user experience is one that as a developer I can live with because even with the overhead on the device it seems to work well enough. I would also like to disclaim this isn’t meant to be a definitive on the subject of the PickerView only a guide so application developers wanting to work with this control can do so without going bald because of the complexities of the control.
I attached the code as a project so building it in xcode and messing around with the parameters shouldn’t be to difficult.


UIPickerViewU.rar (15 K) 下载次数:2121



[ 此帖被kangle1208在2010-07-23 09:09重新编辑 ]


先要我为人人,才有人人为我~~树欲静而风不止;子欲养而亲不待~~百善孝为先~~
级别: 精灵王

UID: 7927
精华: 1
发帖: 315
可可豆: 11333 CB
威望: 11633 点
在线时间: 1658(时)
注册时间: 2009-08-19
最后登录: 2018-11-05
1 楼:  发表于: 2010-07-23 09:03    发自: Web Page
16384可以保证数据滚动时画面的绝对流畅,但是16384,实在有点太多了,我把这个值改一下:

假如当前列的选项数为count, 把16384改为count * 3

pickerViewloaded函数也改一下:
max = count * 3;
base = (max / 2) - (max / 2) % count;
[mypickerview selectRow:[myPickerView selectedRowiInComponent:0] % count + base inComponent:0 animated:NO];

count * 3 这个3可以改成比3大的任何数,但是不能小于3

3的情况下,当数值到了最顶部或者最底部,会先空白一下,然后出现"新的"循环数值~~
(说的什么跟什么啊!?扔东西!!)

个人表达能力差,各位看代码吧~~


先要我为人人,才有人人为我~~树欲静而风不止;子欲养而亲不待~~百善孝为先~~
级别: 精灵王

UID: 14252
精华: 0
发帖: 607
可可豆: 6070 CB
威望: 6070 点
在线时间: 3893(时)
注册时间: 2010-02-20
最后登录: 2016-04-01
2 楼:  发表于: 2010-07-23 12:49    发自: Web Page
那改为10吧,估计够用了,手指不会刨那么快吧

加QQ:3986176联系哦
接外包,不限地区
级别: 骑士
UID: 18380
精华: 0
发帖: 171
可可豆: 1701 CB
威望: 1701 点
在线时间: 277(时)
注册时间: 2010-04-25
最后登录: 2013-04-26
3 楼:  发表于: 2010-07-23 17:25    发自: Web Page
MARK
学习~~
级别: 侠客
UID: 19829
精华: 0
发帖: 58
可可豆: 566 CB
威望: 566 点
在线时间: 101(时)
注册时间: 2010-05-18
最后登录: 2018-03-04
4 楼:  发表于: 2010-09-15 11:19    发自: Web Page
有个 问题,在第一次启动的时候,数据的顶部以上是空的。。。只有当选择过此列后,才能达到循环显示的效果。。有没有什么好的解决方法呢?
级别: 侠客
UID: 42790
精华: 0
发帖: 46
可可豆: 461 CB
威望: 461 点
在线时间: 22(时)
注册时间: 2010-12-15
最后登录: 2013-05-09
5 楼:  发表于: 2011-01-06 11:09    发自: Web Page
mypickerview selectRow:怎么不好用,没有效果,默认还是选中第一个,求真相
级别: 侠客
UID: 46539
精华: 0
发帖: 56
可可豆: 560 CB
威望: 560 点
在线时间: 102(时)
注册时间: 2011-01-12
最后登录: 2013-11-21
6 楼:  发表于: 2011-02-26 09:48    发自: Web Page
标记学习了。。。。
级别: 风云使者

状态: 连续签到 - [25天]
UID: 29025
精华: 0
发帖: 2724
可可豆: 18569 CB
威望: 18611 点
在线时间: 12170(时)
注册时间: 2010-08-29
最后登录: 2019-09-12
7 楼:  发表于: 2011-02-26 10:00    发自: Web Page
回 楼主(kangle1208) 的帖子
学习了
天道酬勤!
级别: 骑士
UID: 34712
精华: 0
发帖: 188
可可豆: 1523 CB
威望: 1523 点
在线时间: 456(时)
注册时间: 2010-10-21
最后登录: 2019-05-07
8 楼:  发表于: 2011-05-30 14:34    发自: Web Page
mark下,我是自己定义个
级别: 精灵王

UID: 53054
精华: 1
发帖: 877
可可豆: 4030 CB
威望: 4030 点
在线时间: 455(时)
注册时间: 2011-02-24
最后登录: 2015-03-28
9 楼:  发表于: 2011-08-03 23:18    发自: Web Page
Mark,my appreciate.
求组队刷本

CocoaChina社区转载内容已尽可能注明出处,如未能核实来源或转发内容图片有权利瑕疵的,请及时联系社区进行修改或删除【联系方式QQ : 3442093904 邮箱:support@cocoachina.com】文章内容为作者独立观点,不代表CocoaChina社区立场。版权归原作者所有,如申请授权请联系作者,因文章侵权CocoaChina社区不承担任何法律及连带责任。

描述
快速回复

关注本帖(如果有新回复会站内信通知您)

发帖、回帖都会得到可观的积分奖励。查看论坛积分规则

按"Ctrl+Enter"直接提交
    顶部