开发者

NSView Not updating?

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)r开发者_StackOverflow中文版ect
{
   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.


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.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜