如何正确使用自定义视图?

| 我一直在尝试制作一个简单的绘图程序。最近,我想出了为此目的在自定义视图中绘制形状的方法。我的问题是我必须在一个时间点上绘制所有内容。我不知道这是否真的有意义,但是在我看来,它只调用一次“ 0”方法,因为“一旦”就启动了。 到目前为止,这是我的代码: 头文件。
NSBezierPath *thePath;
NSColor *theColor;
NSTimer *updateTimer;
NSPoint *mousePoint;
int x = 0;
int y = 0;

@interface test : NSView {
    IBOutlet NSView *myView;

}

@property (readwrite) NSPoint mousePoint;

@end
然后,在.m文件中实施。
@implementation test

@synthesize mousePoint;

- (void) mouseDown:(NSEvent*)someEvent {         
    CGEventRef ourEvent = CGEventCreate(NULL);
    mousePoint = CGEventGetLocation(ourEvent);
    NSLog(@\"Location: x= %f, y = %f\", (float)mousePoint.x, (float)mousePoint.y);
    thePath = [NSBezierPath bezierPathWithRect:NSMakeRect(mousePoint.x, mousePoint.y, 10, 10)];
    theColor = [NSColor blackColor];  

} 

- (void) mouseDragged:(NSEvent *)someEvent {
    mousePoint = [someEvent locationInWindow];
    NSLog(@\"Location: x= %f, y = %f\", (float)mousePoint.x, (float)mousePoint.y);
    x = mousePoint.x;
    y = mousePoint.y;
    [myView setNeedsDisplay:YES];

}

- (void) drawRect:(NSRect)rect; {
    NSLog(@\"oisudfghio\");
    thePath = [NSBezierPath bezierPathWithRect:NSMakeRect(x, y, 10, 10)];
    theColor = [NSColor blackColor];
    [theColor set];
    [thePath fill];

}
@结束 启动时,它会像应该那样在左下角绘制一个矩形。问题是,仅在启动时才调用“ 0”方法。无论我做什么,它都不会开火。 编辑:我刚刚更新了代码。希望对您有所帮助。 第二编辑:我真的简化了代码。我希望这会有所帮助。     
已邀请:
简短答案: 当视图的状态更改为不同的绘制方式时,您需要调用-[NSView setNeedsDisplay:]。这将导致您视图的drawRect:方法在不久的将来被调用。您不应该自己调用drawRect :。这是代表您调用的回调。 当您的应用程序中发生导致您要更改图形的事件时,捕获发生在实例变量中的状态,调用setNeedsDisplay :,然后在调用drawRect:时执行新图形。 长答案: 在可可中,使用拉/失效模型绘制窗口。这意味着窗口具有是否需要绘制的想法,并且在认为需要绘制时,每个事件循环绘制一次。 如果您不熟悉事件循环,可以在Wikipedia上了解它们 在应用程序的顶层,您可以想象Cocoa正在这样做:
while (1) {
   NSArray *events = [self waitForEvents];
   [self doEvents:events];
}
事件是鼠标移动,键盘被按下以及计时器关闭等事件。 NSView具有方法-[NSView setNeedsDisplay:]。它需要一个布尔参数。调用该方法时,窗口将使该视图的绘制区域无效,并计划一个事件以供将来进行重绘-但前提是未计划任何预先存在的重绘事件。 下次运行循环旋转时,将重新绘制标记有setNeedsDisplay:的视图。这意味着您可以连续调用setNeedsDisplay:多次,以后图形将被批量处理到一次drawRect:调用中。出于性能方面的考虑,这非常重要,这意味着您可以通过一种方法执行多次更改视图框架的操作,但只能在最终位置绘制一次。     
您的示例中的代码有两个问题。首先是所有绘图代码必须在
drawRect:
方法中或从
drawRect:
调用的方法中,因此放置在其他方法中的绘图代码在运行时将无效。第二个问题是您的代码永远不要直接调用
drawRect:
。相反,该框架将在每个事件周期自动调用一次(如有必要)。 与其对所有值进行硬编码,不如对您希望在运行时更改的事物使用实例变量,例如,绘图颜色和矩形。然后使用
mouseDragged:
方法,向视图(示例中为
myView
)发送
setNeedsDisplay:
消息。如果您将
YES
作为参数传递,则框架将为您调用
drawRect:
方法。     

要回复问题请先登录注册