首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSView setNeedDisplay:rect导致重新绘制比所需区域更大的区域

NSView setNeedDisplay:rect导致重新绘制比所需区域更大的区域
EN

Stack Overflow用户
提问于 2014-11-27 12:15:36
回答 1查看 427关注 0票数 2

我需要重画一些NSView的一部分。

代码语言:javascript
复制
- (IBAction)onUpdateView:(id)sender
{
    NSRect updatedRect = ... // Redraw updated area only.
    [self.view setNeedsDisplayInRect:updatedRect];
}

当我使用这个简单明了的解决方案时,Quartz Debug突出显示了更大区域的重绘-直到视图的整个区域。

我注意到,如果将NSView setNeedsDisplayInRect的调用推迟到下一个运行循环周期,或者我简单地执行运行循环runUntilDate:+0,问题就会消失:

代码语言:javascript
复制
- (IBAction)onUpdate:(id)sender
{
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [self setNeedsDisplayInRect:updatedRect];
    });
}

代码语言:javascript
复制
- (IBAction)onUpdateAndRunLoop:(id)sender
{
    [self.view setNeedsDisplayInRect:updatedRect];
    [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.0]]; // EEW
}

但是,如果在mouseDown处理程序中调用setNeedsDisplayInRect,它就可以正常工作,而不会遇到这些麻烦:

代码语言:javascript
复制
-(void)mouseUp:(NSEvent*)event
{
    NSPoint p = [self convertPoint:[event locationInWindow] fromView:nil];

    int size = 100;
    [self setNeedsDisplayInRect:NSMakeRect(p.x-size/2, p.y-size/2, size, size)];
}

这是怎么回事,该怎么办?

解决这个问题的独立Xcode项目在这里:http://beta.kalinsky.ru/wtf/testRedraw.tar.gz

EN

回答 1

Stack Overflow用户

发布于 2014-12-04 01:13:06

是什么让你如此确定这是不受欢迎的行为?我在Quartz Debugger下看到的行为显示,当我单击更新按钮时,单击按钮的矩形和传递的dirtyRect的矩形的交叉点会闪烁。这是预期的,因为为了提高效率,系统将所有需要的绘图合并在同一个运行循环中(鼠标打开时)。

您的其他复杂方法绕过了这个行为,因为按钮的状态在一个(实际上是两个:鼠标按下和鼠标释放)过程中处理,而视图的更新在随后的过程中处理。如果您密切关注延迟绘制点击中的更新闪烁(按钮闪烁向下,再次向上,然后视图的脏区闪烁),就会验证这一点。对视图本身的单击不涉及任何其他内容(从技术上讲,是它的非不透明祖先),因此所有视图的脏rect的并集仅限于您所请求的rect。

我希望这能帮到你。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27162964

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档