2013-03-04 103 views
1

我想在我的iOS应用程序中创建一个可缩放的时间线,用于一种待办事项列表。放大会显示几天和几小时,缩小会触发折叠日或缩小到几个月。将会有一个滚动功能。如何在iOS中创建可缩放的时间轴?

举个例子,我希望它是这样工作的:http://almende.github.com/chap-links-library/js/timeline/doc/

什么样的基本观点的将是这一个恰当的起点,牢记应尽可能低所需的内存?一个UITableView,UIScrollView,或其他的工作呢?

+0

这个问题可能需要一些编辑,但我的理解是,这是一个有效的问题。 – Luke 2013-03-06 00:42:36

+0

你有没有考虑过Core绘图? https://code.google.com/p/core-plot/ – 2013-03-11 23:53:47

+0

PM我,如果你仍然在寻找 – Chris 2015-05-31 02:49:33

回答

0

UITableView绝对不适合。 UIScrollView可能会更好,但它不适合动态或非常长的内容。

我相信easist的方法就是自己做所有事情 - 通过的子类drawRect实现它。当然,您应该使用UIPanRecognizer,方法与UIScrollView使用它相同。

+0

感谢的人我用这种方法取得良好进展 – 2013-03-08 14:42:51

+1

我只想指出,一个UIScrollView是超过适合非常长的内容 - 如果你平铺和回收单元格,就像UITableView和UICollectionView一样。这意味着任何你看不到的东西都会被移除并回收。对UIView进行子类化并重写'drawRect'既不容易也不重要,特别是如果你期望与元素交互或者动画运动。 – Luke 2013-03-08 17:14:58

+0

@Luke你对'UIScrollView'的建议基本上和你使用drawRect所做的一样。相信我,动画并没有什么困难,因为scrollview所做的一切都是基于来自泛识别器的数据改变水平和垂直偏移量。重写'drawRect'并不复杂,用'UIScrollView'重复使用视图并不复杂。而且,它更符合记忆。我刚完成自己的可滚动组件,并且交互或动画没有问题。 – Sulthan 2013-03-08 17:25:42

7

UICollectionView/UITableView将不起作用,因为单元格几乎总是相同的宽度/高度。最重要的是,细胞总是在每个细胞之间具有相同的间距。因此,它能够轻松计算出索引范围,并根据索引查询其需要的单元。

另一方面,时间轴视图与这些控件有很大不同。单元格之间的间距不同,单元格有时会彼此重叠。如果你有一个按位置排序的数据源,那么控件仍然会猜测从哪里开始寻找范围。因此,找到正确的索引范围将会更加昂贵 - 您只需找到合适的算法以在较短的时间内确定这一点。

您将不得不通过继承UIScrollView来构建自己的控件。你根本不应该混淆drawRect。一个重要的概念,UITableViewUICollectionView使用,是dequeue'ing细胞。苹果公司的PhotoScroller的iOS 5版本通过分页演示了这个概念(iOS 6版本用UIPageViewController代替了自定义分页)。您必须登录download the old documentation才能获取旧的示例代码。

我目前正在构建一个时间轴视图,我将在某些时候开放源代码。它有点基于UITableView,可以在水平或垂直方向工作。它像UITableView一样出列细胞。我并不关注标签或缩放,而是关注单元之间间距不一致的概念。为了给你一个良好的开端,这里有我的数据源方法,我对解决:

- (NSInteger)numberOfCellsInTimelineView:(TimelineView *)timelineView; 
- (CGRect)timelineView:(TimelineView *)timelineView cellFrameForIndex:(NSInteger)index; 
- (TimelineViewCell *)timelineView:(TimelineView *)timelineView cellForIndex:(NSInteger)index; 

这些电话中的两个相同的东西UITableView了,但它有一个名为cellFrameForIndex新的呼叫。这次调用的重要意义在于TimelineView可以猜出一个索引并查找单元格的框架,并查看它适合可见边界的位置。如果它猜测可见边界内的单元格,它可以简单地向前和向后迭代,直到找到边缘。

目前我正在使用的算法需要round(count * (CGRectGetMidX(timelineView.bounds)/timelineView.contentSize.width))(水平方向)。基本上这是做了UIScrollView的可见边界的中点,并获得已滚动的百分比。然后它乘以单元的数量。这工作相当好。当以随机间隔测试一个具有100,000条记录的随机数据集时,cellFrameForIndex的范围为8到150.我可以用这个来拉52-60 FPS。我仍在努力,并试图找到一种更好/更快的方式来确定指数范围。我试图将它保持在可见细胞数+10(最大)迭代次数。

如果您有时间等待,我会更新我的答案,以便在完成后包含指向我的GitHub项目的链接。这可能是几天,一周。我可以添加缩放。但是你必须将它分叉并添加标签和其他你想要的东西。

编辑:

这里是我的Github上的项目:https://github.com/lukescott/TimelineView

+1

'UICollectionView'使得no关于其细胞的大小或位置的假设。使用自定义的'UICollectionViewLayout',您可以实现非常灵活的布局,甚至不必成为栅格... – omz 2013-03-06 19:43:33

+0

间距仍然必须一致且已知,而不必查看数据源,这是关键区别。 – Luke 2013-03-06 19:54:22

+1

我想知道你是如何得出这个结论的。 – omz 2013-03-06 22:09:21