Jus*_*tin 0 cocoa objective-c nsview
我一直在尝试制作一个简单的绘图程序.最近,我已经想出为此目的在自定义视图中绘制形状.我的问题是我必须在一个时间点绘制所有内容.我不知道这是否真的有意义,但在我看来它只调用drawRect
一次方法,因为"一次"是在启动时.
到目前为止,这是我的代码:
头文件.
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
Run Code Online (Sandbox Code Playgroud)
然后,在.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];
}
Run Code Online (Sandbox Code Playgroud)
@结束
在启动时,它会在左下角绘制一个矩形,就像它应该的那样.问题是,该drawRect
方法仅在启动时调用.无论我做什么,它都不会开火.
编辑:我刚刚更新了代码.我希望它有所帮助.
第二次编辑:我真的简化了代码.我希望这会有所帮助.
简答: 当您的视图状态发生更改以使其绘制方式不同时,您需要调用 - [NSView setNeedsDisplay:].这将导致您的视图的drawRect:方法在不久的将来被调用.你永远不应该打电话给drawRect:你自己.这是一个代表你调用的回调.
当您的应用程序中发生导致您想要更改绘图的事件时,请捕获实例变量中发生的事件的状态,调用setNeedsDisplay:然后在调用drawRect:时执行新绘图.
长答案: 在Cocoa中,窗口绘图是使用拉/无效模型完成的.这意味着窗口会知道它是否需要绘制,当它认为需要绘制时,它会在每个事件循环中绘制一次.
如果您不熟悉事件循环,可以在Wikipedia上阅读它们
在应用程序的顶层,您可以想象Cocoa正在这样做:
while (1) {
NSArray *events = [self waitForEvents];
[self doEvents:events];
}
Run Code Online (Sandbox Code Playgroud)
事件是鼠标移动,键盘按下,定时器关闭等.
NSView有一个方法 - [NSView setNeedsDisplay:].它需要一个布尔参数.当调用该方法时,窗口使该视图的绘图区域无效,并调度事件以供将来进行重绘 - 但仅限于未安排预先存在的重绘事件.
当runloop下次旋转时,将重新绘制使用setNeedsDisplay:标记的视图.这意味着您可以连续多次调用setNeedsDisplay:并且绘图将被批量调用到将来的一次drawRect调用:这对于性能原因很重要,这意味着您可以在一个方法中多次更改视图的框架,但只能在最终位置绘制一次.
归档时间: |
|
查看次数: |
610 次 |
最近记录: |