Cocoa NSView未更新?

Cocoa NSView未更新?,cocoa,drag-and-drop,nsview,redraw,nscolor,Cocoa,Drag And Drop,Nsview,Redraw,Nscolor,我正在一个拖放视图上工作,并在web上找到了一些拖放操作的处理程序。我想让它在用户拖动文件到拖放区域时变为蓝色,在用户退出拖放区域时变为灰色。问题在于,当您将鼠标拖动到它或退出它时,它不会更新。以下是一些代码: - (void)drawRect:(NSRect)rect { NSRect bounds = [self bounds]; [[NSColor grayColor] set]; [NSBezierPath fillRect:bounds]; } - (NSDragO

我正在一个拖放视图上工作,并在web上找到了一些拖放操作的处理程序。我想让它在用户拖动文件到拖放区域时变为蓝色,在用户退出拖放区域时变为灰色。问题在于,当您将鼠标拖动到它或退出它时,它不会更新。以下是一些代码:

- (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)drawRect:(NSRect)rect
{
NSRect界限=[自界限];
[[NSColor grayColor]集];
[NSBezierPath fillRect:bounds];
}
-(NSDragOperation)DragginGeted:(id)发送方{
NSRect界限=[自界限];
[[NSColor blueColor]set];
[NSBezierPath fillRect:bounds];
返回NSDRAGO操作副本;
}

-(无效)拖动退出:(id)发送方{
NSRect界限=[自界限];
[[NSColor grayColor]集];
[NSBezierPath fillRect:bounds];
}


谢谢您的帮助。

您是否在任何地方拨打
[yourView:setNeedsDisplay]


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

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


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

只有在为您设置要绘制的上下文(如用于绘制的画布)时,绘制才起作用。当框架调用
-drawRect:
时,它已经为您设置了一个绘图上下文,因此像
-[NSColor set]
-[NSBezierPath fillRect:
这样的绘图命令可以按您的预期工作

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

在99.99%的情况下,所有视图图形都应保存在
-drawRect:
中,因为NSView做了许多您不想做的工作,以便正确有效地设置图形上下文

那么,如何在
-draggingEntered:
-draggingExited:
方法中更改视图的图形?副作用

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

- (void)draggingEntered:(id <NSDraggingInfo>)sender {
    drawBlueColorIvar = YES;
    // ...
}
(注意我没有使用
[self-bounds]
。如果可能的话,只画“dirty”rect更有效。)


最后,您需要某种方法来告诉框架,当drawBlueColorIvar发生更改时,您的视图需要重新绘制。框架不会绘制任何东西,除非它被告知需要绘制。正如Chris Cooper所说,您可以通过
[自我设置需求显示:是]
来实现这一点。这应该在您更改的任何位置之后进行
drawBlueColorIvar

只有在设置了要绘制的上下文(如用于绘制的画布)时,绘图才起作用。当框架调用
-drawRect:
时,它已经为您设置了一个绘图上下文,因此像
-[NSColor set]
-[NSBezierPath fillRect:
这样的绘图命令可以按您的预期工作

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

在99.99%的情况下,所有视图图形都应保存在
-drawRect:
中,因为NSView做了许多您不想做的工作,以便正确有效地设置图形上下文

那么,如何在
-draggingEntered:
-draggingExited:
方法中更改视图的图形?副作用

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

- (void)draggingEntered:(id <NSDraggingInfo>)sender {
    drawBlueColorIvar = YES;
    // ...
}
(注意我没有使用
[self-bounds]
。如果可能的话,只画“dirty”rect更有效。)


最后,您需要某种方法来告诉框架,当drawBlueColorIvar发生更改时,您的视图需要重新绘制。框架不会绘制任何东西,除非它被告知需要绘制。正如Chris Cooper所说,您可以通过
[自我设置需求显示:是]
来实现这一点。这应该放在您更改的任何位置之后
drawBlueColorIvar

我添加了[self-setNeedsDisplay:YES];每次画完后都没有运气。将nslog添加到其中表明方法正在被触发;每次画完后都没有运气。添加一个nslog显示这些方法正在被触发。我对cocoa还是有点陌生,还没有听说过ivar。当我尝试编译时,我得到一个错误:“drawBlueColorIvar”未声明(在这个函数中首次使用),这似乎是合乎逻辑的,因为我还没有声明它。如何声明ivar?哦,我知道了,我刚刚添加了NSColor*drawBlueColorIvar;到视图标题。谢谢你的帮助!我对可可还是有点陌生,还没有听说过ivar。当我尝试编译时,我得到一个错误:“drawBlueColorIvar”未声明(在这个函数中首次使用),这似乎是合乎逻辑的,因为我还没有声明它。如何声明ivar?哦,我知道了,我刚刚添加了NSColor*drawBlueColorIvar;到视图标题。谢谢你的帮助!
- (void)drawRect:(NSRect)rect {
    NSColor *color = drawBlueColorIvar ? [NSColor blueColor] : [NSColor grayColor];
    [color set];
    [NSBezierPath fillRect:rect];
}