2013-02-21 111 views
3

我是编程,objective-c(和stackoverflow)的新手。我正在学习,并且进展缓慢;)但后来我遇到了一个谷歌无法解决的问题。我有一个窗口和一个NSview,然后添加了一个鼠标事件,该事件应该将坐标绘制到我的视图中,但事实并非如此。有趣的是:它是绘制当鼠标移过我的应用程序窗口的窗口按钮...通过鼠标事件绘制成NSView

- (void)drawRect:(NSRect)dirtyRect { 
    NSPoint imagePos = NSMakePoint(0, 0); 
    NSImage *aImage = [NSImage imageNamed:@"mw_bg01.png"]; 
    [aImage dissolveToPoint:imagePos fraction:1.0]; 
} 
- (void)mouseDown:(NSEvent*)theEvent;{ 
    mouseLoc = [NSEvent mouseLocation]; 
    mousePosX = mouseLoc.x;mousePosY = mouseLoc.y; 
    NSString* mouseString = [NSString stringWithFormat:@"%d", mousePosX]; 
    NSPoint textPoint = NSMakePoint(5, 5); 
    NSMutableDictionary *textAttrib = [[NSMutableDictionary alloc] init]; 
    [textAttrib setObject:[NSFont fontWithName:@"Helvetica Light" size:10] 
       forKey:NSFontAttributeName]; 
    [textAttrib setObject:[NSColor grayColor] forKey:NSForegroundColorAttributeName]; 
    [mouseString drawAtPoint:textPoint withAttributes:textAttrib]; 
} 

我不知道怎么去,有什么建议?谢谢!

+0

此代码是什么?它看起来像你写了一个mouseDown处理程序。取决于代码的位置(例如,在应用程序中,或者在视图中或其他方面),它可能仅仅是在哪里它恰好是按钮的委托而不是视图。 – podperson 2013-02-21 22:18:59

+0

它在视图中。我带了一个mouseDown处理程序,因为我想在我的视图中测试绘图,并且mousemove没有被调用。 – fw2601 2013-02-21 22:25:34

+0

并且:我没有任何按钮,我的意思是3个OSX窗口按钮... – fw2601 2013-02-21 22:37:59

回答

5

您不应该在-mouseDown:方法中进行绘图。相反,您必须在-drawRect:(或您从-drawRect:拨打电话的方法)中完成所有绘图。试试这样的:

@interface MyView() 
    @property NSPoint lastMousePoint; 
@end 

@implementation MyView 

- (void)drawLastMousePoint 
{ 
    NSString *mouseString = NSStringFromPoint(self.lastMousePoint); 
    NSPoint textPoint = NSMakePoint(5, 5); 
    NSMutableDictionary *textAttrib = [[NSMutableDictionary alloc] init]; 
    [textAttrib setObject:[NSFont fontWithName:@"Helvetica Light" size:10] 
       forKey:NSFontAttributeName]; 
    [textAttrib setObject:[NSColor grayColor] forKey:NSForegroundColorAttributeName]; 
    [mouseString drawAtPoint:textPoint withAttributes:textAttrib]; 
} 

- (void)drawRect:(NSRect)dirtyRect 
{ 
    NSPoint imagePos = NSMakePoint(0, 0); 
    NSImage *aImage = [NSImage imageNamed:@"mw_bg01.png"]; 
    [aImage dissolveToPoint:imagePos fraction:1.0]; 

    [self drawLastMousePoint]; 
} 

- (void)mouseDown:(NSEvent*)theEvent; 
{ 
    self.lastMousePoint = [theEvent locationInWindow]; 
    [self setNeedsDisplay:YES]; 
} 

@end 

当你得到一个鼠标按下事件,你只需将鼠标的位置存储下来。图纸在-drawLastMousePoint中完成,您可以在-drawRect:方法中调用。既然您知道只要点击鼠标就需要重新绘制,您可以致电-setNeedsDisplay:通知视图需要重绘。请注意,重绘不会立即发生,相反,它会在下一次通过运行循环时发生。换句话说,你的意思是说:“嘿,改变了一些事情,我需要再次画出我的观点内容,请尽快再次致电-drawRect:!”

另外一个注意事项:+[NSEvent mouseLocation]确实是设计用于获取当前鼠标位置以外的事件流。通常,在-mouseDown:方法中,您调用-locationInWindow上的NSEvent作为参数传递给方法。如果您需要转换为本地/视图坐标,则应调用[self convertPoint:[theEvent locationInWindow] fromView:nil];

+0

谢谢。我需要学习很多;) 但有一件事:当我打电话给setNeedsDisplay时,它也会绘制mw_bg01.png,对不对?这很慢,不是吗? – fw2601 2013-02-21 22:47:56

+0

我们都是全新的在一个点:)。是的,它会再次绘制PNG。你不应该提前担心这会很慢,而应该测试一下,看看它是否足够慢,实际上有所作为,然后才花时间改变它的工作方式。一般来说,在屏幕上绘制静态PNG是相当快的。如果您确实需要提高性能,那么有几个选项,包括:仅重绘视图的一部分(请参阅'-setNeedsDisplayInRect:'),在不同视图中绘制鼠标点,该视图是当前视图的子视图,使用CALayers等 – 2013-02-21 23:06:13

+0

@ fw2601难道这不适合你吗?你为什么不接受答案? – 2013-02-22 18:33:32