【问题标题】:How to implement a timeline custom control with cocoa?如何用可可实现时间线自定义控件?
【发布时间】:2011-10-31 12:11:14
【问题描述】:

我的 Cocoa 应用程序收集需要在时间轴中显示的事件(NSManagedObject 的实例)。我最初的方法是使用现有的基于 Javascript 的小部件(我尝试使用 Simile Timeline 和 Timeglider)并使用 WebView 控件显示时间线。这原则上可行,但不幸的是,这两个小部件都不能很好地处理 BC 日期,这是我的应用程序的一个重要要求。

我的应用中的事件的日期范围从公元前 500.000 到最近的日期。事件日期仅以年份表示。它们的日、月和时间属性无关紧要。

放弃 Javascript 方法后,我仍然可以选择使用自定义 Cocoa 控件显示时间线。由于我发现没有合适的,我将不得不自己开发。

这将是我的第一个自定义 Cocoa 控件,经过一段时间的思考,我想出了以下粗略的设计:

  • 我需要一个自定义控件来呈现实际的时间线。此控件可能基于 NSView。此控件应根据时间线上的刻度线数量乘以每个标记之间的宽度(像素)来计算其大小。例如,时间线由世纪组成,每个世纪 100 像素宽。公元前 10.000 年和公元前 5.000 年之间的事件时间线将是 5000 像素宽(10000 - 5000 = 5000 年,等于 50 个世纪)。

  • 我需要一个 ScrollView 来包装时间线以使其支持滚动行为。只需要水平滚动。

  • 我需要一些东西来代表一个实际的事件。我正在考虑为此使用现有的控件,可能是标准的圆形按钮和包装在一起作为单个控件的标签。

  • 我需要一个自定义控件来在时间线上呈现刻度线。

将此作为我在 Cocoa 中的时间线组件的基本设计,这样会有效还是我完全没有抓住重点?

【问题讨论】:

  • 罗杰,你有没有做到这一点?我遵循了类似的时间表(仅涵盖 24 小时)。
  • @Darren 是的,我做到了。效果很好。我刚刚完成了对初始设计的重大重构。
  • @Roger 你有 iPhone 的示例代码吗?我有类似的要求??

标签: cocoa custom-controls timeline


【解决方案1】:

基本方法听起来不错。

Apple 有一个很好的例子来创建一个名为“TreeView”的自定义 NSView。这是一个很好理解的示例。

https://developer.apple.com/library/mac/#samplecode/TreeView/Introduction/Intro.html#//apple_ref/doc/uid/DTS40010131

“TreeView”展示了一个创建全新自定义的示例 从头开始查看(通过直接继承 NSView)。其实施 说明了创建自定义项所涉及的许多注意事项 视图,包括内容布局、绘图、处理用户的问题 交互,并提供辅助功能支持。

您可能需要考虑的另一件事是放大和缩小。如果您的时间线很长,我想您可能想要缩小然后放大一组活动。如果您在 10k BC 有一个事件,然后在很久以后有一组事件,则用户可以滚动浏览大量空白空间以尝试查找事件。另一种方法是在上面有一个适合/静态大小的迷你时间线,这有点像带有显示活动点的线条的索引 - 然后单击它会自动滚动到该点。根据您的数据,这可能会很好。

一些想法:

对于这种自定义绘制的东西,您需要覆盖 drawRect 来绘制线条并布置子控件。

如果您正在绘制背景或视图的任何部分,请确保启用支持图层的视图:

[self setWantsLayer:YES];

如您所述,如果可以,请尝试利用您添加和布局的现有控件。在我的自定义控件中,我维护了独立于表示所有对象状态的视图/控件的数据结构。在 drawRect 中,我检测到视图发生了变化,并调用了我的 layoutSubviews 函数。我的 layoutSubViews 函数将从我的数据结构中进行数学运算,并创建或移动现有控件的框架。这对于调整大小和缩放效果很好。如果您缩放,您的标签广告标记需要对缩放非常小做出良好反应 - 可能文本在某些时候会丢失等...

if ([self dataSource] && 
    !NSEqualRects(_prevRect, [self bounds]))
{
    // layoutViews is my custom function that worked over the data structures
    // and moved the frame
    [self layoutViews];
}

_prevRect = [self bounds];

希望对您有所帮助。

【讨论】:

  • 谢谢。关于缩放的好点。我尝试过的其中一个 Javascript 小部件具有带有迷你时间线的功能。暂时我会把它放在一边以增加#2 :-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-10-02
  • 2014-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-21
相关资源
最近更新 更多