Quartz——有时它从一个空白视图开始,有时它不是

Posted

技术标签:

【中文标题】Quartz——有时它从一个空白视图开始,有时它不是【英文标题】:Quartz -- sometimes it starts from a blank view and sometimes it doesn't 【发布时间】:2010-07-03 02:14:44 【问题描述】:

我面前有两个 Quartz iPhone 应用程序。在它们中的每一个中,对 setNeedsDisplay 的调用都会导致视图自身重绘。但是有一个重要的区别。在一种情况下(Mark/Lamarche 书籍“Beginning iPhone development”中的“Quartz Fun”应用程序),每次开始时视图都是空白的。在另一种情况下(我正在开发的应用程序),视图从以前的任何内容开始,并在其上添加新图形。

我不明白这是为什么。谁能帮我解答一下?

谢谢。

编辑#2:我仍然不明白这里发生了什么。但是我发现我可以通过调用来清除我的视图

CGContextRef context = UIGraphicsGetCurrentContext();
CGContextClearRect(context, self.frame);

编辑#3:显示缩短的代码:

根据评论者的建议,我已经编辑了我的应用程序,因此只需很少的代码就会出现问题。 [现在问题的形式有点不同,如下所述。]

应用委托:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions   
    DiceView *dv = [[DiceView alloc]initWithFrame: window.frame];
    [window addSubview:dv];

    [dv release];
    [window makeKeyAndVisible];
    return YES;

骰子视图:

- (void)drawRect:(CGRect)rect 
    static int nDrawrectCalls = 0;
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetLineWidth(context, 1.0);
    CGContextSetStrokeColorWithColor(context, (nDrawrectCalls%5==0?[UIColor redColor]:[UIColor greenColor]).CGColor);
    CGContextMoveToPoint(context, 10, 30+10*nDrawrectCalls);
    CGContextAddLineToPoint(context, 300, 30+10*nDrawrectCalls);
    CGContextStrokePath(context);
    nDrawrectCalls++;
 

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event   
    [self setNeedsDisplay];

其他一切都只是默认的存根方法。

现在来看看区别。它现在似乎开始使用两次触摸之前屏幕上的任何内容进行绘制。换句话说,在 touch #2 之后,我看到了最初的行,加上 touch #2 的行——但不是 touch #1 的行。在 touch #3 之后,我看到 touch #1 和 #3 的线条。在 touch #4 之后,我看到了初始行以及 touch #2 和 #4 的行。以此类推。

【问题讨论】:

贴出“在其上添加新图形”的代码 【参考方案1】:

UIView 有一个 clearsContextBeforeDrawing 布尔属性,可以在您描述的不同行为之间切换。默认值为 YES,这意味着视图在调用 drawRect: 之前清空上下文

检查该属性是否在示例中的某处设置。

显然,当视图上没有设置背景颜色时,视图无法正确清除其上下文。请将 backgroundColor 设置为 nil 以外的值。

我认为这是一个错误并已提交rdar://8165730。


编辑

这不是错误。您必须将 opaque 属性设置为 NO 或 backgroundColor。 UIView 文档中描述了该行为。

属性clearsContextBeforeDrawing

此属性的默认值为 是的。当设置为 YES 时,当前 图形上下文缓冲区 drawRect: 方法是自动的 之前清除为透明黑色 drawRect: 被调用。如果视图的 opaque 属性也设置为 YES, 的 backgroundColor 属性 view 不能为 nil 或绘图错误 可能会发生。

如果此属性的值为 NO, 这是视图的责任 完全填满它的内容。绘画 如果这样做可以提高性能 属性为否——例如,当 滚动。

属性opaque

如果它是不透明的,则为YES;否则,否。如果 不透明,绘图操作假定 视图填充了它的边界并且可以 画得更有效率。结果是 如果不透明和视图不可预测 没有填满它的界限。设置这个 如果视图完全或 部分透明。默认 值为 YES。

【讨论】:

好点。 . .但我检查了,属性设置为YES。但是,不清楚。 你是直接调用drawRect:吗?你在后台线程上调用 setNeedsDisplay 吗?您是否在后台线程上调用任何 UIKit 方法或函数?你在用这个视图层做些什么吗?如果所有答案都是否定的:尝试将您的代码减少到重现问题所需的最低限度。只有一个将视图添加到窗口的 appDelegate 和在 touchesEndedWithEvent 中调用 setNeedsDisplay 的视图: 尝试设置背景颜色,见上

以上是关于Quartz——有时它从一个空白视图开始,有时它不是的主要内容,如果未能解决你的问题,请参考以下文章

滚动表格视图时单元格变为空白(swift)

如何获取此代码的输出。有时它显示输出,有时它不显示?

使用 CURL 保存图像,有时它会保存空白图像

OpenCV VideoCapture 有时会返回空白帧

Quartz入门 Job管理

Quartz任务调度Quartz从入门到入土(史上最详细)