5

我的应用程序中有一个 NSView 的自定义子类。我想知道视图中的确切点,相对于它的原点,是用鼠标单击的。(即不是相对于窗口原点,而是相对于自定义视图原点)。

我一直使用这个,效果很好:

-(void)mouseDown:(NSEvent *)theEvent
{
    NSPoint screenPoint = [NSEvent mouseLocation];
    NSPoint windowPoint = [[self window] convertScreenToBase:screenPoint];
    NSPoint point = [self convertPoint:windowPoint fromView:nil];

    _pointInView = point;

    [self setNeedsDisplay:YES];
}

但是现在我收到一个警告说convertScreenToBase已被弃用,而是使用convertRectFromScreen。但是我不能从 convertRectFromScreen 得到相同的结果,而且无论如何,我对一个点感兴趣,而不是一个矩形!

我应该使用什么来正确替换上面不推荐使用的代码?提前致谢!

4

4 回答 4

6

您的代码中的这一行:

    NSPoint screenPoint = [NSEvent mouseLocation];

使鼠标光标的位置与事件流不同步。这不是您当前正在处理的事件的位置,这是过去很短的时间;它现在是光标的位置,这意味着您可能会跳过一些重要的东西。您几乎应该始终使用与事件流同步的位置。

为此,请使用theEvent您的方法接收的参数。NSEvent有一个locationInWindow属性,它已经被转换为接收它的窗口的坐标。这消除了您转换它的需要。

    NSPoint windowPoint = [theEvent locationInWindow];    

您将窗口位置转换为视图坐标系的代码很好。

于 2015-05-30T07:57:09.580 回答
4

我找到了解决方案:

NSPoint screenPoint = [NSEvent mouseLocation];
NSRect screenRect = CGRectMake(screenPoint.x, screenPoint.y, 1.0, 1.0);
NSRect baseRect = [self.window convertRectFromScreen:screenRect];
_pointInView = [self convertPoint:baseRect.origin fromView:nil];
于 2015-06-01T11:41:28.453 回答
3

我制作了一个带有窗口的示例项目并测试了“旧”和新场景。两种情况下的结果是相同的。

你必须做一个额外的步骤:创建一个以 screenPoint 为原点的简单矩形。然后使用新返回的矩形的原点。

这是新代码:

-(void)mouseDown:(NSEvent *)theEvent
{
    NSPoint screenPoint = [NSEvent mouseLocation];
    NSRect rect = [[self window] convertRectFromScreen:NSMakeRect(screenPoint.x, screenPoint.y, 0, 0)];

    NSPoint windowPoint = rect.origin;
    NSPoint point = [self convertPoint:windowPoint fromView:nil];

    _pointInView = point;

    [self setNeedsDisplay:YES];
}

我希望我能帮助你!

于 2015-05-29T08:29:44.323 回答
1

简单地使用convert(_:from:)可能不准确,当事件的窗口和视图的窗口不同时会发生这种情况。请检查我在另一个问题中的答案以获得更可靠的方式。

https://stackoverflow.com/a/69784415/3164091

于 2021-10-31T06:26:47.130 回答