NSView 不更新?

发布于 2024-09-10 10:13:00 字数 704 浏览 9 评论 0原文

我正在研究拖放视图,并找到了一些用于在网络上进行拖放操作的处理程序。我想让它在用户将文件拖动到拖放区域时变为蓝色,并在退出拖放区域时再次变为灰色。问题是当您将鼠标拖动到它上面或退出它时它不会更新。这是一些代码:

- (void)drawRect:(NSRect)rect
{
   NSRect bounds = [self bounds];
   [[NSColor grayColor] set];
   [NSBezierPath fillRect:bounds];
}

- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender  {
    NSRect bounds = [self bounds];
    [[NSColor blueColor] set];
    [NSBezierPath fillRect:bounds];

    return NSDragOperationCopy;

}

- (void)draggingExited:(id <NSDraggingInfo>)sender {
    NSRect bounds = [self bounds];
    [[NSColor grayColor] set];
    [NSBezierPath fillRect:bounds];

}

感谢您的帮助。

Im working on a drag n' drop view and found some handlers for drag and drop actions on the web. I want to make it so it turns blue when the user drags a file over the drag and drop area and gray again when they exit the drag and drop area. The issues is its not updating when you drag your mouse over it or exit it. Heres some of the code:

- (void)drawRect:(NSRect)rect
{
   NSRect bounds = [self bounds];
   [[NSColor grayColor] set];
   [NSBezierPath fillRect:bounds];
}

- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender  {
    NSRect bounds = [self bounds];
    [[NSColor blueColor] set];
    [NSBezierPath fillRect:bounds];

    return NSDragOperationCopy;

}

- (void)draggingExited:(id <NSDraggingInfo>)sender {
    NSRect bounds = [self bounds];
    [[NSColor grayColor] set];
    [NSBezierPath fillRect:bounds];

}

Thanks for any help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

ゝ杯具 2024-09-17 10:13:00

您是否在任何地方调用 [yourView: setNeedsDisplay]

通过这种方式,您可以让绘图框架知道它需要使用 drawRect: 向您的 UIView 子类发送消息,因此只要情况发生变化,您就应该执行此操作。就您而言,这可能意味着鼠标进入或退出放置区域时。

Are you calling [yourView: setNeedsDisplay] anywhere?

This is how you let the drawing framework know it needs to message your UIView subclass with drawRect:, so you should do it whenever things have changed. In your case, this probably means when the mouse enters or exits the drop area.

扛刀软妹 2024-09-17 10:13:00

仅当设置了供您绘制的上下文(例如用于绘画的画布)时,绘图才有效。当框架调用 -drawRect: 时,它已经为您设置了绘图上下文,因此绘图命令如 -[NSColor set]-[NSBezierPath fillRect:] 按您的预期工作。

-drawRect: 之外,通常不会设置绘图上下文。在 -drawRect: 之外使用绘图命令就像在空中挥舞画笔;没有画布,所以不会进行绘画。

在 99.99% 的情况下,所有视图绘制都应保留在 -drawRect: 内,因为 NSView 做了很多您不想做的工作来正确有效地设置绘图上下文。

那么,如何在 -draggingEntered:-draggingExited: 方法中更改视图的绘制呢?通过副作用。

在所有三种情况下,您都在做同样的事情:1)设置颜色和2)绘制矩形。唯一的区别是每种方法的颜色变化。那么,为什么不使用 ivar 来控制在 -drawRect: 中使用哪种颜色,如下所示:

- (void)draggingEntered:(id <NSDraggingInfo>)sender {
    drawBlueColorIvar = YES;
    // ...
}

然后在 -drawRect: 中执行以下操作:(

- (void)drawRect:(NSRect)rect {
    NSColor *color = drawBlueColorIvar ? [NSColor blueColor] : [NSColor grayColor];
    [color set];
    [NSBezierPath fillRect:rect];
}

注意我没有使用[selfbounds]。如果可能的话,直接绘制到“脏”矩形会更有效。)

最后,您需要某种方法来告诉框架当drawBlueColorIvar更改时您的视图需要重绘。除非被告知需要,否则框架不会绘制任何内容。正如 Chris Cooper 所说,您可以使用 [self setNeedsDisplay:YES] 来执行此操作。这应该位于您更改drawBlueColorIvar的任何位置之后。

Drawing only works when a context (like a canvas for painting) is set up for you to draw into. When the framework calls -drawRect: it has set up a drawing context for you, so drawing commands like -[NSColor set] and -[NSBezierPath fillRect:] work as you expect.

Outside of -drawRect: there is usually no drawing context set up. Using drawing commands outside of -drawRect: is like waving a paintbrush in the air; there's no canvas, so no painting happens.

In 99.99% of cases, all view drawing should be kept within -drawRect: because NSView does a lot of work that you don't want to do to get the drawing context set up correctly and efficiently.

So, how do you change your view's drawing within your -draggingEntered: and -draggingExited: methods? By side effects.

You're doing the same thing in all three cases: 1) Setting a color and 2) Drawing a rectangle. The only difference is the color changes in each method. So, why not control which color you use in -drawRect: with an ivar, like so:

- (void)draggingEntered:(id <NSDraggingInfo>)sender {
    drawBlueColorIvar = YES;
    // ...
}

Then in -drawRect: you do this:

- (void)drawRect:(NSRect)rect {
    NSColor *color = drawBlueColorIvar ? [NSColor blueColor] : [NSColor grayColor];
    [color set];
    [NSBezierPath fillRect:rect];
}

(Notice I didn't use [self bounds]. It is more efficient to just draw into the "dirty" rect, when possible.)

Finally, you need some way to tell the framework that your view needs to redraw when drawBlueColorIvar changes. The framework won't draw anything unless it's told it needs to. As Chris Cooper said, you do this with [self setNeedsDisplay:YES]. This should go after any place you change drawBlueColorIvar.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文