我想在我的iOS应用程序中创建一个可缩放的时间轴,用于一种待办事项列表。放大将显示天数和小时,缩小将触发折叠天数或缩小到月份。应该有一个滚动功能
作为一个例子,我希望它像这样工作:http://almende.github.com/chap-links-library/js/timeline/doc/
什么样的基本视图将是一个合适的起点,记住所需的内存应该尽可能低?UITableView, UIScrollView,或者其他的东西可以吗?
UICollectionView
/UITableView
将不工作,因为单元格几乎总是相同的宽度/高度。最重要的是,每个单元格之间总是有相同的间距。因此,它可以很容易地计算出索引范围是什么,并根据索引查询dataSource
中需要的单元格。
另一方面,时间轴视图与这些控件有很大不同。细胞之间的间距是不同的,细胞有时彼此重叠。如果数据源按位置排序,控件仍然需要猜测从哪里开始查找范围。因此,找到正确的索引范围将是更昂贵的-你只需要找到正确的算法,在较短的时间内确定它。
你将不得不通过子类化UIScrollView
来构建你自己的控件。你根本不应该把drawRect
弄乱。UITableView
和UICollectionView
使用的一个重要概念是单元格的脱队列。iOS 5版本的苹果PhotoScroller通过分页展示了这个概念(iOS 6版本用UIPageViewController
取代了自定义分页)。您必须下载旧的文档才能获得旧的示例代码。
我目前正在构建一个时间轴视图,我将在某个时候开放源代码。它有点基于UITableView
和工作在水平或垂直方向。它像UITableView
一样去排队。我关注的不是标签或缩放,而是细胞之间不一致间距的概念。为了让您有一个良好的开端,以下是我选定的dataSource方法:
- (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。我仍在努力,并试图找到一个更好/更快的方法来确定索引范围。我试图保持它的可见细胞计数+ 10(最大)迭代。
如果你有时间等待,我会更新我的答案,包括一个链接到我的GitHub项目当我完成。可能是几天,也可能是一周。我可以添加缩放。但是你必须fork它并添加标签和其他你想要的东西。
编辑:这是我的Github项目:https://github.com/lukescott/TimelineView
UITableView
绝对不合适。UIScrollView
可能更好,但它不太适合动态或很长的内容。
我相信最简单的方法是自己做所有事情-通过UIView
子类与drawRect
实现它。当然,您应该像UIScrollView
那样使用UIPanRecognizer
。