2

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

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

什么样的基本视图将是一个合适的起点,记住所需的内存应该尽可能低?UITableView、UIScrollView 或其他东西会为此工作吗?

4

2 回答 2

8

UICollectionView/将UITableView不起作用,因为单元格几乎总是相同的宽度/高度。最重要的是,单元格在每个单元格之间始终具有相同的间距。正因为如此,它能够很容易地计算出索引范围是什么,并根据索引查询dataSource它需要的单元格。

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

您将不得不通过子类化 a 来构建自己的控件UIScrollView。你根本不应该惹麻烦drawRectUITableView和使用的一个重要概念UICollectionView是出列单元格。Apple 的PhotoScroller的 iOS 5 版本通过分页演示了这一概念(iOS 6 版本将自定义分页替换为UIPageViewController)。您必须下载旧文档才能获取旧示例代码。

我目前正在构建一个时间线视图,我将在某个时候将其开源。它有点基于UITableView和 在水平或垂直方向上工作。它像UITableView. 我不关注标签或缩放,而是单元格之间间距不一致的概念。为了让您抢占先机,以下是我选择的 dataSource 方法:

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

其中两个调用与UITableViewhas 相同,但它有一个名为 的新调用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

于 2013-03-06T19:20:44.013 回答
0

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

我相信最简单的方法是自己做所有事情——通过一个UIView带有drawRect. 当然,您应该以与使用它UIPanRecognizer相同的方式UIScrollView使用它。

于 2013-03-06T17:29:48.350 回答