Quartz——有时它从空白视图开始,有时则不是
我面前有两个 Quartz iPhone 应用程序。在每个视图中,调用 setNeedsDisplay 都会导致视图重绘自身。但有一个重要的区别。在一种情况下(Mark/Lamarche 书籍“Beginning iPhonedevelopment”中的“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;
}
DiceView:
- (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];
}
其他一切都只是默认的存根方法。
现在来说说区别。现在,它似乎开始使用两次触摸之前屏幕上的任何内容进行绘制。换句话说,在触摸 #2 后,我看到了初始线,加上触摸 #2 的线,但看不到触摸 #1 的线。在触摸 #3 后,我看到触摸 #1 和 #3 的线条。在触摸 #4 后,我看到了初始行以及触摸 #2 和 #4 的行。等等。
I have in front of me two Quartz iPhone apps. In each of them, calls to setNeedsDisplay cause a view to redraw itself. But there is an important difference. In one case (the "Quartz Fun" app from the Mark/Lamarche book "Beginning iPhone development"), the view starts out blank each time. In the other case (the app I am working on), the view starts with whatever was there before, and new graphics are added on top of it.
I can't figure out why this is. Can anyone clue me in?
Thanks.
EDIT #2: I still don't understand what is going on here. But I have figured out that I can clear my view by calling
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextClearRect(context, self.frame);
EDIT #3: showing shortened code:
As a suggested by a commenter, I have edited my app so that the issue occurs with very little code. [The form of the issue is a bit different now, as explained below.]
App delegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
DiceView *dv = [[DiceView alloc]initWithFrame: window.frame];
[window addSubview:dv];
[dv release];
[window makeKeyAndVisible];
return YES;
}
DiceView:
- (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];
}
Everything else is just default stub methods.
Now for the difference. It now appears to start drawing with whatever was on the screen two touches prior. In other words, after touch #2, I see the initial line, plus the line from touch #2 -- but not the line from touch #1. After touch #3, I see the lines from touches #1 and #3. After touch #4, I see the initial line and the lines from touches #2 and #4. And so on.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
UIView
有一个clearsContextBeforeDrawing
布尔属性,可以在您描述的不同行为之间切换。默认值为 YES,这意味着视图在调用 DrawRect: 之前清空上下文:检查该属性是否在示例中的某处设置。
显然,当视图上没有设置背景颜色时,视图无法正确清除其上下文。请将背景颜色设置为 nil 以外的值。
我认为这是一个错误,并已提交 rdar://8165730。
编辑
这不是一个错误。您必须将不透明属性设置为“NO”或“backgroundColor”。 UIView 文档中描述了该行为。
属性
clearsContextBeforeDrawing
:属性
不透明
:UIView
has aclearsContextBeforeDrawing
boolean property that switches between the different behaviors you describe. The default is YES which means the view empties the context before callingdrawRect:
Check if that property is set somewhere in the example.
Apparently a view doesn't clear it's context correctly, when no backgroundColor is set on the view. Please set backgroundColor to something other than nil.
I think this is a bug and have filed rdar://8165730.
EDIT
It's not a bug. You have to set the opaque property to NO or the backgroundColor. The behavior is described in the UIView Documentation.
Property
clearsContextBeforeDrawing
:Property
opaque
: