setNeedsDisplayInRect:导致整个视图被更新 [英] setNeedsDisplayInRect: causes the whole view to be updated

查看:76
本文介绍了setNeedsDisplayInRect:导致整个视图被更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发使用CoreGraphics进行渲染的绘画应用程序。我的问题是,为了提高性能,我试图将更新限制为仅更改了视图的某些部分。为此,我使用setNeedsDisplayInRect :,但是有时视图会更新其全部内容,从而导致结结。这在第三代iPad上尤为明显,但在模拟器和iPad2中也较小。我试图消除这种现象。

I'm working on a painting app that uses CoreGraphics for rendering. My problem is, for performance, I am trying to limit the updates to only certain portions of the view that have changed. For that, I use setNeedsDisplayInRect:, but sometimes the view updates its entire content, causing stuttering. This is particularly evident on the 3rd generation iPads, but it also happens in the simulator and the iPad2 to a lesser degree. I am trying to remove this behavior.

为了展示这个问题,我使用Xcode中的模板创建了一个简单的单视图项目。创建了一个自定义UIView子类,我将其设置为xib文件中的视图控制器视图。

To showcase the problem, I created a simple "single view" project using the template in Xcode. Created a custom UIView subclass which I set as the view controller's view in the xib file.

将其添加到UIViewController中:

Added this to the UIViewController:

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    // Asks that the view refreshes a smal rectangle
    [self.view setNeedsDisplayInRect:CGRectMake(10, 10, 20, 20)];
}

将此添加到MyView(我的自定义视图)中:

Added this to the MyView (my custom view):

- (void)drawRect:(CGRect)rect
{
    // Just log what is being updated
    NSLog(@"%@", NSStringFromCGRect(rect));
}

就是这样。如果我在第十三个iPad(实际设备)上运行该应用程序,则日志会显示视图不时对其自身进行重绘(例如非常频繁)。这太令人沮丧了,我没主意了

And that's it. If I run the app on the 3rd ten iPad (the actual device), the logs show the view repainting itself in its entierty from time to time (like very frequently). This is so frustrating and I am out of ideas

更新:这是一些日志。它肯定显示了有时会更新的完整视图。我正在尝试使其完全停止,但无法弄清楚如何...

UPDATE: Here are some logs. It definitely shows the full view being updated sometimes. I am trying to make it stop completely but can't figure how to...

2012-05-04 08:34:01.851 TestUpdateArea[45745:707] {{0, 0}, {320, 460}}
2012-05-04 08:34:30.184 TestUpdateArea[45745:707] {{0, 0}, {320, 460}}
2012-05-04 08:34:30.197 TestUpdateArea[45745:707] {{0, 0}, {320, 460}}
2012-05-04 08:34:30.215 TestUpdateArea[45745:707] {{10, 10}, {20, 20}}
2012-05-04 08:34:30.226 TestUpdateArea[45745:707] {{10, 10}, {20, 20}}
2012-05-04 08:34:30.242 TestUpdateArea[45745:707] {{10, 10}, {20, 20}}
2012-05-04 08:34:30.258 TestUpdateArea[45745:707] {{10, 10}, {20, 20}}
2012-05-04 08:34:30.274 TestUpdateArea[45745:707] {{10, 10}, {20, 20}}
2012-05-04 08:34:30.290 TestUpdateArea[45745:707] {{10, 10}, {20, 20}}
2012-05-04 08:34:30.306 TestUpdateArea[45745:707] {{10, 10}, {20, 20}}
2012-05-04 08:34:30.322 TestUpdateArea[45745:707] {{10, 10}, {20, 20}}
2012-05-04 08:34:30.338 TestUpdateArea[45745:707] {{10, 10}, {20, 20}}
2012-05-04 08:34:30.354 TestUpdateArea[45745:707] {{10, 10}, {20, 20}}
2012-05-04 08:34:30.371 TestUpdateArea[45745:707] {{10, 10}, {20, 20}}
2012-05-04 08:34:30.387 TestUpdateArea[45745:707] {{10, 10}, {20, 20}}
2012-05-04 08:34:30.403 TestUpdateArea[45745:707] {{10, 10}, {20, 20}}
2012-05-04 08:34:30.419 TestUpdateArea[45745:707] {{10, 10}, {20, 20}}
2012-05-04 08:34:30.439 TestUpdateArea[45745:707] {{0, 0}, {320, 460}}
2012-05-04 08:34:30.457 TestUpdateArea[45745:707] {{10, 10}, {20, 20}}

此外,如果我停止移动超过10秒钟左右并恢复,那肯定是非常一致的:

Also if I stop moving for over 10s or so and resume, it definitely does it very consistently:

2012-05-04 08:34:33.305 TestUpdateArea[45745:707] {{10, 10}, {20, 20}}
2012-05-04 08:34:33.321 TestUpdateArea[45745:707] {{10, 10}, {20, 20}}
2012-05-04 08:35:00.202 TestUpdateArea[45745:707] {{0, 0}, {320, 460}}
2012-05-04 08:35:00.221 TestUpdateArea[45745:707] {{0, 0}, {320, 460}}
2012-05-04 08:35:00.234 TestUpdateArea[45745:707] {{0, 0}, {320, 460}}
2012-05-04 08:35:00.251 TestUpdateArea[45745:707] {{10, 10}, {20, 20}}


推荐答案

检查这个苹果文档

说:


由于iPhone / iPod touch / iPad更新屏幕的方式,如果重新绘制
的整个视图,您调用 -setNeedsDisplayInRect:
-setNeedsDisplay:


每个UIView被视为一个元素。当您通过调用 -setNeedsDisplayInRect: -setNeedsDisplay:来部分或全部重画时,整个视图将标记为更新。

Each UIView is treated as a single element. When you request a redraw, in part or whole, by calling -setNeedsDisplayInRect: or -setNeedsDisplay:, the entire view will be marked for updates.

所以我认为您需要使用子视图来更新整个View的独立矩形。

so I think you need to use subviews to update independent rect of the whole View.

这篇关于setNeedsDisplayInRect:导致整个视图被更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆