构建自定义UIPickerView

时间:2013-03-27 09:35:06

标签: ios uikit uipickerview

我正在尝试构建一个自定义UIPickerView替换类,主要用于学习目的,但我希望在我正在开发的应用程序中实现它。我已经花了很多时间和精力进入我的应用程序的UI,现在默认的UIPickerView不合适。

我看到这个Dribble嘲笑了一个非常光滑的日期/时间选择器,但我意识到UIPickerView可以在没有一些重大黑客的情况下大量定制UIPickerView。{/ p >

经过大量阅读和调查后,我发现UITableView使用UIScrollView代替它的组件,而不是我原先假设的普通UITableViewCell。这有点令人困惑,原因有两个:

自定义UIPickerView是一个主要的痛苦。这并不是说它很辛苦,只是费力而且很少产生所需的结果。不知何故,UITableViewCellStyleDefault设法通过很少的开销来解决这个问题。我假设组件中的每一行只使用contentView并为其UIPickerView提供自定义视图,但您知道他们对假设的看法。

让我失望的第二件事是UITableViewDataSource符合UITableViewDelegate协议,但不符合– tableView:heightForRowAtIndexPath:协议。这似乎有点奇怪,因为代表负责通过UIPickerView – pickerView:rowHeightForComponent:提供正确的高度,但允许您通过pagingEnabled

设置组件的大小

与此一致,使用表视图似乎也是一个奇怪的选择,因为它们不会像滚动视图与UIPickerView一样“捕捉”到指定的行。

任何人都可以解释为什么默认UIScrollView不符合上述代表吗?我是否更容易使用UITableView来实现我的自定义选择器,或者{{1}}是否应该提供所需的功能?

3 个答案:

答案 0 :(得分:3)

  1. UIPickerView实际上符合UITableViewDelegate协议,但不公开在公共标头中。您可以使用class_copyProtocolList函数自行检查。

  2. 在内部使用UITableView可以更容易地实现具有大量行的选择器,因为UITableView为重用单元格提供了很好的支持,否则Apple需要再次为选择器重新实现该逻辑 - 这没有多大意义(抱歉,我没有看到在这种情况下自定义UITableViewCell有任何大问题,因此很难对此进行评论)

  3. 由于UITableView是UIScrollView子类,您可以将其“捕捉”到特定位置,在scrollViewWillEndDragging:withVelocity:targetContentOffset:协议中检查可用于此目的的UIScrollViewDelegate方法。

答案 1 :(得分:0)

自定义UIPickerView是通过使用包含字段所需数量UIViewController的{​​{1}}子类来模仿其行为来完成的。

例如:如果你想要一个时间选择器,请使用2个tableviews

您应该使用图像等在xib中设置样式。

重现行为的难点是UITableView“捕捉”到最近的单元格,尤其是正确的部分。

此外,UIPickerView中的单元格很简单,单元格之间没有边框/分隔符,文本标签居中,voilà。你看到的只是覆盖在UIPickerView s前面的图像。

至于为什么完全不符合UITableView,这是因为事实上,它是一个轻量级UITableViewDelegate自动捕捉UITableView内部使用的UIPickerView 1}}。因此,它缺少一些对此没有特别用处的代表。

但我想我们都同意一件事:确实,构建自定义UIPickerView是一件很大的痛苦,应该会更容易。

看看这个组件,看起来很不错,虽然我自己没有测试过。 computerlogicx/AFPickerView

答案 2 :(得分:0)

我成功实施了一个"替代品" UIPicker扩展UICollectionView

虽然UICollectionView通常用于某个部分中有多个项目的情况,但您只能拥有一个项目并且工作正常。如果您启用分页,则会获得与UIPicker类似的行为,但它有一个“粘性”"滚动,只允许您一次滚动一个项目,如果这是你想要的可能会更好。此外,您可以垂直或水平滚动。您甚至可以使用带有一些额外代码的2D选择器。