【问题标题】:Flipped NSView mouse coordinates翻转 NSView 鼠标坐标
【发布时间】:2019-01-20 18:25:43
【问题描述】:

我有一个 NSView 的子类,它重新实现了一些鼠标事件函数。例如在 mouseDown 中从我使用的 NSEvent 中获取要点:

NSEvent *theEvent; // <- argument to function

NSPoint p = [theEvent locationInWindow];
p = [self convertPoint:p fromView:nil];

但是坐标好像是翻转的,(0, 0)在窗口的左下角?

编辑:我已经重写了 isFlipped 方法以返回 TRUE,但它只影响了绘图。抱歉,真不敢相信我忘了马上把它放好。

【问题讨论】:

    标签: macos cocoa


    【解决方案1】:

    你说的翻转是什么意思? Mac 对所有内容都使用 LLO(左下原点)坐标系。

    编辑我无法用一个简单的项目重现这一点。我创建了一个 NSView 实现如下:

    @implementation FlipView
    - (BOOL)isFlipped {
      return YES;
    }
    
    - (void)mouseDown:(NSEvent *)theEvent {
      NSPoint p = [theEvent locationInWindow];
      p = [self convertPoint:p fromView:nil];
      NSLog(@"%@", NSStringFromPoint(p));
    }
    @end
    

    我收到了我期望的坐标。删除isFlipped 按预期切换方向。你有一个简单的项目来展示你的问题吗?

    【讨论】:

    • 我的意思是,我已经覆盖了 isFlipped 方法。我的错,我说得不够清楚。
    • 在我的测试中,如果您使用 convertPoint:fromView:isFlipped { YES } 将该点转换为左上角原点。但是不是如果你使用 convertPoint:toV​​iew:——这是意料之中的,因为toView: 假定该点​​已经在self 视图的坐标系中。
    【解决方案2】:

    我觉得这太令人讨厌了 - 直到有一天,我只是坐下来拒绝起床,直到我找到了完美的东西。这里是……通过……调用。

    -(void) mouseDown:(NSEvent *)click{
      NSPoint mD = [NSScreen wtfIsTheMouse:click
                            relativeToView:self];
    }
    

    在 NSScreen 上调用一个类别......

    @implementation NSScreen (FlippingOut)
    + (NSPoint)wtfIsTheMouse:(NSEvent*)anyEevent 
              relativeToView:(NSView *)view {
       NSScreen *now = [NSScreen currentScreenForMouseLocation];
        return [now flipPoint:[now convertToScreenFromLocalPoint:event.locationInWindow relativeToView:view]];
    }
    - (NSPoint)flipPoint:(NSPoint)aPoint {
             return (NSPoint) { aPoint.x, 
       self.frame.size.height - aPoint.y  };
    }
    - (NSPoint)convertToScreenFromLocalPoint:(NSPoint)point 
          relativeToView:(NSView *)view {
        NSPoint winP, scrnP, flipScrnP; 
        if(self) {
           winP = [view convertPoint:point toView:nil];
           scrnP = [[view window] convertBaseToScreen:winP];
           flipScrnP = [self flipPoint:scrnP];
           flipScrnP.y += [self frame].origin.y;
           return flipScrnP;
           }    return NSZeroPoint;
    }
    @end
    

    希望这可以防止只发生一次轻微的freakout.. 某天,某天。为了孩子,该死的。我求求你了……为了孩子们。

    【讨论】:

      【解决方案3】:

      这段代码对我有用:

      NSPoint location =  [self convertPoint:theEvent.locationInWindow fromView:nil];
      location.y = self.frame.size.height - location.y;
      

      【讨论】:

        【解决方案4】:

        这不一定是“翻转”的,这正是 Quartz 进行坐标的方式。 An excerpt from the documentation on Quartz 2D:

        用户空间中的点由坐标对 (x,y) 表示,其中 x 表示沿水平轴(左右)的位置,y 表示垂直轴(上下)。用户坐标空间的原点是点 (0,0)。原点位于页面的左下角,如图 1-4 所示。在 Quartz 的默认坐标系中,x 轴随着它从页面的左侧向右侧移动而增加。 y 轴的值随着从页面底部向顶部移动而增加。

        不过,我不确定您的问题是什么。您是否正在寻找一种获得“翻转”坐标的方法?如果是这样,您可以继承您的 NSView,覆盖 -(BOOL)isFlipped 方法以返回 YES。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-04-30
          • 1970-01-01
          相关资源
          最近更新 更多