如何在iOS中创建可缩放的时间轴?

时间:2013-03-04 08:47:15

标签: ios iphone objective-c timeline chap-links-library

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

作为一个例子,我希望它能像这样工作:http://almende.github.com/chap-links-library/js/timeline/doc/

什么样的基本观点才是适当的起点,请记住所需的内存应该尽可能低? UITableView,UIScrollView或其他什么东西可以用于此吗?

2 个答案:

答案 0 :(得分:7)

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

另一方面,时间轴视图与这些控件有很大不同。细胞之间的间隔是不同的,细胞有时彼此重叠。如果您有按位置排序的数据源,则控件仍然需要猜测从哪里开始查找范围。因此,找到正确的指数范围将会更加昂贵 - 您只需要找到正确的算法,以便在更短的时间内确定这一点。

您必须通过继承UIScrollView来构建自己的控件。你根本不应该混淆drawRectUITableViewUICollectionView使用的一个重要概念是将单元格出列。 Apple的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 :(得分:0)

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

我认为简单的方法是自己做所有事情 - 用UIView子类和drawRect实现。当然,您应该使用UIPanRecognizerUIScrollView使用它的方式相同。