【问题标题】:Is setNeedsDisplay *always* repainting?setNeedsDisplay *总是*重绘吗?
【发布时间】:2011-09-06 16:54:44
【问题描述】:

我使用 cocoa 编写了一个小的自定义视图应用程序。后来(是的,我知道这很糟糕)我只是问自己:这也适用于可可粉吗?当然 id 并没有立即起作用,我不得不更改类名等等。好吧,我在需要时使用NSTimersetNeedsDisplay: 方法刷新了视图。在可可下工作得很好,但在可可触摸下绝对不行。

我无法向自己解释,实际上我不知道哪些代码行可以帮助某人解决问题。也许这里是计时器:

[self setMyTimer: [NSTimer scheduledTimerWithTimeInterval:0.03 target:self selector:@selector(myTarget:) userInfo:nil repeats:YES]];

它的目标:

- (void) myTarget:(NSTimer *)timer {
    [self setNeedsDisplay];
}

计时器每 30 毫秒调用一次,我使用 NSLog 进行了检查。

drawRect: 方法中,我实际上只是画了一些形状,没有做任何其他事情。以防万一需要调用某种clearRect: 方法。正如我所说,在可可下它工作。

【问题讨论】:

  • 试试[self setNeedsDisplay:YES];
  • @WTP:这似乎在 iPhone 上,它没有 setNeedsDisplay: 方法,只有无参数 setNeedsDisplay (这真的很有意义,因为我没有我想我曾经写过setNeedsDisplay:NO,除了有一次我很好奇它是否有任何作用)。

标签: objective-c cocoa-touch cocoa custom-view setneedsdisplay


【解决方案1】:

我将首先使用断点或日志语句来验证drawRect: 是否正在运行。

然后,确保您的视图确实在屏幕上。 [self superview] 的值是多少?您还应该执行self.backgroundColor = [UIColor redColor]; 之类的操作,这样您就可以看到您的视图在哪里。

仅仅因为您每 30 毫秒将视图标记为脏并不意味着它会每 30 毫秒绘制一次。它通常应该(大约 30fps),但不能保证。 drawRect: 不应该依赖于它被调用的频率。根据您的问题,我假设您的意思是它从不绘图,而不是像预期的那样经常绘图。

【讨论】:

  • 其实,我忘了说:视图是在设置时绘制的。我想这需要视图在屏幕上,不是吗?在自定义视图初始化之后,drawRect:-方法不再被调用。我只是试图通过调用NSLog(@"%@", [self superview]); 来获取[self superview] 的值。这打印(空)到控制台。看起来像一个线索,但没有告诉我解决方案。
  • 这意味着您不再出现在屏幕上。实施willMoveToSuperview: 以了解您何时被删除。
  • Betcha 有两个不同的视图类实例,一个闲置在屏幕上,另一个正在更新。
  • @Chuck 的建议是一个很常见的问题,你一定要看看。
  • @Valentin Rüchardt:调查@Chuck 建议的第一步是在didMoveToSuperview 和@ 中记录self 的指针值(%p,这会产生类似0xd3c2b1a0 的东西) 987654331@。如果这两种方法记录了不同的指针值,则表明您创建了两个单独的视图,而视图层次结构中的视图(因此,能够绘制)不是您提供计时器的视图。
【解决方案2】:

这是UIView 的文档中关于setNeedsDisplay 的讨论(注意缺少参数):

您可以使用此方法通知系统您的视图的内容 需要重新绘制。此方法记录请求并 立即将控制权返回给您的代码。观点不 实际重绘直到下一个绘图周期,此时所有 更新无效的视图。

您应该使用此方法请求仅在以下情况下重绘视图 视图的内容或外观发生变化。如果你只是改变 视图的几何形状,通常不会重绘视图。相反,它的 现有内容根据视图中的值进行调整 contentMode 财产。重新显示现有内容会改进 通过避免重绘未完成的内容来提高性能 改变了。

相比之下,这里是NSView的文档中关于setNeedsDisplay:的讨论(注意参数):

每当用于绘制视图对象的数据或状态发生变化时, 视图应发送setNeedsDisplay: 消息。 NSView 标记的对象 根据需要显示在每次通过时自动重新显示 应用程序的事件循环。 (查看需要重新显示的对象 在事件循环出现之前当然可以立即发送 适当的显示...方法。)

【讨论】:

  • 我不确定我是否走在正确的轨道上,但 NSView 不是可可风格的视图吗?我实际上是在可可触摸中,我在 Interface Builder 中添加的自定义视图向我展示了,它们是 UIViews。所以我选择了 UIView-class 作为继承类(对不起,英语不是我的母语。我说的是类,我的类是继承自。)实际上,在 UIView 中没有方法 setNeedsDisplay:。
  • @Valentin:正如帖子所述,UIView 拥有 setNeedsDisplayNSView 拥有 setNeedsDisplay:。前者适用于 iOS,后者适用于 OSX。
  • 啊抱歉,我确实读完了。但这告诉我什么?所以我在绘图周期中提出了重新绘制的请求。这个重复的速度有多快?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-09
  • 1970-01-01
  • 1970-01-01
  • 2021-05-31
相关资源
最近更新 更多