重新实现 UIPickerView

参考资料:

http://www.cocoachina.com/bbs/read.php?tid=85374

http://www.cocoachina.com/iphonedev/toolthain/2011/1205/3663.html

设置循环滚动

设置 UIPickerView 的数据源数量为很大的规模, 取数据时对行数进行取模, 从而实现循环滚动的效果.

在每次滚动结束后, 把当前选这个行无动画滚动到数据的中间, 减少用户滚动到数据边界的可能.

参考资料:

http://www.cocoachina.com/bbs/read.php?tid=27023

http://code4app.com/codesample/4f67fbb96803fa833f000002

http://blog.csdn.net/ipromiseu/article/details/7436521

修改滚动速度

比较困难. 需要继承 UIPickerView, 并实现未公开函数

- (double)scrollAnimationDuration

参考资料:

http://iphonedevelopment.blogspot.com/2009/01/longer-spinning-blurring.html

需要FQ, 把原文章复制过来.

Longer Spinning & Blurring

I can't tell you how many times I've been asked lately how to do the "UrbanSpoon Effect".

Note: There is a newer version of this code available here.

Now, I have no idea exactly how the folks at UrbanSpoon did their application, but they did it well. I don't have time for a full tutorial right now, or to do a full implementation of the effect, but in the process of helping somebody in a forum, I did write a little sample application that shows the basic theory of how to make your UIPickerView go round and round for longer.

As I said, this project nowhere near as polished as what UrbanSpoon does - I cheated on the blurring because I hit some bugs while porting my NSImage convolution kernel code to work with UIImage and I don't have the time to debug something that gnarly right now. My "blur" is just a double resize - down then back up. It's really just interpolation, but it sorta makes it blurry. I probably wouldn't use that method of blurring in a real application but, then again, I'd be getting paid for a real application.

This application does support using the accelerometer to start the spin. In order to make the picker view spin longer, I subclassedUIPickerView. My subclass had exactly one method. This is an undocumented method that returns the duration of the spin, so you just return the number of seconds you want your spin to go for:

#import "JLPickerView.h"

@implementation JLPickerView- (double)scrollAnimationDuration{return 5.0;}@end

The other key thing to note in this application is that my UIPickerViewDataSource lies about how many rows each component has. I have a constant called kRowMultiplier. I take the count of the array that corresponds to a particular component, and I multiply it by kRowMultiplier. This value is currently set to 100, so if the array that feeds a component has ten items, my datasource lies and says there are a thousand, and then it just keeps feeding the same ten items over and over in the same order by calculating the actual row in the array to use:

int actualRow = row%[[self arrayForComponent:component] count];

This creates a component with the same values repeated over and over.

When the view first appears, I load arrays with views containing both the blurred and unblurred data. You don't want to be programmatically blurring the values over and over when the spin happens, so we do it once and store the values in arrays. I then set the component's row to a value in the middle. This means that the user will never see the blank rows above and below the real values, which helps create the illusion of endless spinning.

[picker selectRow: [component1Data count] * (kRowMultiplier / 2) inComponent:0 animated:NO];

Now, when a value is selected in the picker, I do a bait-and-switch back to the middle. I move the component to the same value they're currently on, but back in the middle of the wheel. This way, no matter what happens, they'll never see the blank rows at the top or bottom. Since I'm moving them to the same value and the surrounding values are the same, and I tell it not to animate the change, the user has no idea it has happened.

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{NSArray *componentArray = [self arrayForComponent:component];int actualRow = row%[componentArray count];

int newRow = ([componentArray count] * (kRowMultiplier / 2)) + actualRow;[picker selectRow:newRow inComponent:component animated:NO];

}

Finally, when the spin button is pressed, or the user shakes the phone, I calculate a random number for each component. This number is a value between 0 and the size of the array minus 1. This tells me what the new, randomly selected value will be. Then I move the components (again, without animating) to the corresponding row near the top or bottom of the dial, and then animate to the selected value at the other end of the wheel.

- (IBAction)spin{   if (! isSpinning)    {// Calculate a random index in the array        spin1 = arc4random()%[component1Data count];        spin2 = arc4random()%[component1Data count];        spin3 = arc4random()%[component1Data count];    

// Put first and third component near top, second near bottom        [picker selectRow:([picker selectedRowInComponent:0]%[component1Data count]) + [component1Data count] inComponent:0 animated:NO];[picker selectRow:(kRowMultiplier - 2) * [component2Data count] + spin2 inComponent:1 animated:NO];[picker selectRow:([picker selectedRowInComponent:2]%[component3Data count]) + [component3Data count] inComponent:2 animated:NO];

// Spin to the selected value        [picker selectRow:(kRowMultiplier - 2) * [component1Data count] + spin1 inComponent:0 animated:YES];[picker selectRow:spin2 + [component2Data count] inComponent:1 animated:YES];[picker selectRow:(kRowMultiplier - 2) * [component3Data count] + spin3 inComponent:2 animated:YES];

        isSpinning = YES;

// Need to have it stop blurring a fraction of a second before it stops spinning so that the final appearance is not blurred.        [self performSelector:@selector(stopBlurring) withObject:nil afterDelay:4.7];    }}

I set a variable called isSpinning so that I know whether to provide blurred or unblurred data to the spinner. I have the spin set for 5 seconds, so 4.7 seconds in the future, I set the value back to NO. This cause it to stop blurring a moment before the spinning stops. This is done so that the final words displayed will not be blurred.

You can download the sample project here.

One note, though: I have used a couple of undocumented, private methods in this project. I ordinarily shy away from doing that, but in the sake of getting this code out the door quickly, I did. I use one undocumented method for resizing the UIImage in order to create the fake blur effect, and another one to keep the picker from making sounds when I initially set the values because I don't want the user to realize I'm moving the picker - that would shatter the illusion. These are pretty subtle uses of undocumented methods so I doubt they'd get your application rejected, but they could. They're also not methods that are likely to change. But, again, they could - that's always a risk with undocumented methods, so caveat emptor - use at your own risk. If you want to play it safe, to a real motion blur and take out the calls to UIPickerView's setSoundsEnabled: method.

ios UIPickerView 技巧集锦相关推荐

  1. Unity 4.x游戏开发技巧集锦(内部资料)

    2019独角兽企业重金招聘Python工程师标准>>> Unity 4.x游戏开发技巧集锦(内部资料) 淘宝书店地址:http://item.taobao.com/item.htm? ...

  2. Unity 游戏开发技巧集锦之使用cookie类型的纹理模拟云层的移动

    Unity 游戏开发技巧集锦之使用cookie类型的纹理模拟云层的移动 使用cookie类型的纹理模拟云层的移动 现实生活中,当阳光直射大地,而天空中又有很多云时,云层的影子总是会投射在大地上,风吹着 ...

  3. Unity 游戏开发技巧集锦之创建透明的材质

    Unity 游戏开发技巧集锦之创建透明的材质 Unity创建透明的材质 生活中不乏透明或者半透明的事物.例如,擦的十分干净的玻璃,看起来就是透明的:一些塑料卡片,看起来就是半透明的,如图3-23所示. ...

  4. Unity 游戏开发技巧集锦之创建部分光滑部分粗糙的材质

    Unity 游戏开发技巧集锦之创建部分光滑部分粗糙的材质 创建部分光滑部分粗糙的材质 生活中,有类物体的表面既有光滑的部分,又有粗糙的部分,例如丽江的石板路,如图3-17所示,石板的表面本来是粗糙的, ...

  5. Unity 游戏开发技巧集锦之创建自发光材质

    Unity 游戏开发技巧集锦之创建自发光材质 创建自发光材质 自发光材质(self-illuminated material)是指自己会发光的材质.生活中与之相似的例子,就是液晶显示屏上显示的信息,文 ...

  6. ​Unity 游戏开发技巧集锦之制作一个望远镜与查看器摄像机

    ​Unity 游戏开发技巧集锦之制作一个望远镜与查看器摄像机 Unity中制作一个望远镜 本节制作的望远镜,在鼠标左键按下时,看到的视图会变大:当不再按下的时候,会慢慢缩小成原来的视图.游戏中时常出现 ...

  7. Unity游戏开发技巧集锦2.1.3实现效果

    Unity游戏开发技巧集锦2.1.3实现效果 将此脚本加到Camera对象上,选中此对象,即可查看对象上此脚本组件中的各项属性,如图2-4所示. 图2-4  对象脚本组件里的各项属性          ...

  8. Unity 4.x游戏开发技巧集锦第2章摄像机的应用

    Unity 4.x游戏开发技巧集锦第2章摄像机的应用 作为游戏开发者,千万不要忽略了摄像机(Camera)的重要性.毕竟玩家是通过摄像机,才看到了游戏的视图.本章将介绍一些摄像机的常见应用.本文选自& ...

  9. C++ Builder技巧集锦

    C++ Builder技巧集锦 1 /* 2 调用DOS程序时不显示窗口 3 使 用 ShellExecute调 用 DOS程 序 时 可 以 不 显 示 窗 口 , 如 :*/ 4 ShellExe ...

最新文章

  1. Docker Dockerfile
  2. android 添加附件功能,Android实现带附件的邮件发送功能
  3. windows 只能同时 启动一个_一个u盘能否刻入win 7、win10等多个系统?该怎么做?...
  4. java api管理工具_一个能快速写出实体类的Api文档管理工具
  5. FireDAC 中文字段过滤问题
  6. java上机题四取三排列_java语言特性概述
  7. 二进制漏洞挖掘_漏洞挖掘的艺术-面向二进制的静态漏洞挖掘
  8. Vue中computed分析
  9. MongoDB副本集配置系列二:配置MongoDB副本集
  10. php修改sessiob时间_php中session过期时间设置
  11. js上传文件转二进制格式
  12. SpringMVC使用AJAX上传图片
  13. 多节点部署执行定时任务选举单一节点解决方案---redis
  14. Quartz是什么?
  15. MOOC 苏小红C语言 第四周编程题
  16. Hello hello world♥
  17. 代码简短且隐蔽的后门木马
  18. es 索引操作(创建、查看、删除)
  19. 基于vue的适老化住宅设计系统的设计与实现
  20. 防火墙iptables原理及简单应用

热门文章

  1. goland远程调试Docker
  2. Effective C++学习第十一天
  3. 组件文件已损坏或android内部模块,android - Android Q更新后,模块化系统组件在托管配置文件中不可用 - 堆栈内存溢出...
  4. linux 编译3g驱动_linux下使用3G拨号上网 以及3g驱动设置
  5. 每日一题:leetcode1319.联通网络的操作次数
  6. 文件操作(stat函数)
  7. 九大经典算法之基数排序、桶排序
  8. 动态库(共享库)的制作和使用
  9. 大话数据结构——算法
  10. 关于LaaS,PaaS,SaaS一些个人的理解