当父不是窗口时,有没有办法获得相对于最内层NSView的坐标?

Ped*_*ues 15 cocoa

我对NSView有疑问:

想象一下自定义视图,其中mouseDown,mouseDrag和mouseUp方法被覆盖,因此用户可以在屏幕上拖动一个点(NSRect).要拖动它,我需要相对于当前视图的鼠标坐标.当视图的父级是窗口时,这不是问题,但是当视图在另一个视图中时,如何获取它们?

@implementation MyView

- (id)initWithFrame:(NSRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        pointXPosition = 200.0f;
        pointYPosition = 200.0f;

        locked = NO;
    }
    return self;
}

- (void) drawRect:(NSRect)rect {

    NSRect point = NSMakeRect(pointXPosition, pointYPosition, 6.0f, 6.0f);
    [[NSColor redColor] set];
    NSRectFill(point);

}

- (void)mouseDown:(NSEvent *)theEvent {
    NSPoint mousePos = [theEvent locationInWindow];
    NSRect frame = [super frame];
    CGFloat deltaX = mousePos.x - frame.origin.x - pointXPosition;
    CGFloat deltaY = mousePos.y - frame.origin.y - pointYPosition;
    if(sqrtf(deltaX * deltaX + deltaY * deltaY) < 100.0f)
        locked = YES;
}

- (void)mouseUp:(NSEvent *)theEvent {
    locked = NO;
}

- (void)mouseDragged:(NSEvent *)theEvent {

    if(locked) {
        NSPoint mousePos = [theEvent locationInWindow];

        NSRect frame = [super frame];

        CGFloat oldXPos = pointXPosition;
        CGFloat oldYPos = pointYPosition;

        pointXPosition = mousePos.x - frame.origin.x;
        pointYPosition = mousePos.y - frame.origin.y;

        CGFloat rectToDisplayXMin = MIN(oldXPos, pointXPosition);
        CGFloat rectToDisplayYMin = MIN(oldYPos, pointYPosition);

        CGFloat rectWidthToDisplay = MAX(oldXPos, pointXPosition) - rectToDisplayXMin;
        CGFloat rectHeigthToDisplay = MAX(oldYPos, pointYPosition) - rectToDisplayYMin;

        NSRect dirtyRect = NSMakeRect(rectToDisplayXMin,
                                      rectToDisplayYMin,
                                      rectWidthToDisplay + 6.0f,
                                      rectHeigthToDisplay + 6.0f);

        [self setNeedsDisplayInRect:dirtyRect];
    }
}
Run Code Online (Sandbox Code Playgroud)

Jas*_*oco 26

您无需手动转换为本地坐标系.您可以通过将convertPoint:fromView:消息发送到视图来将点转换为本地坐标系.发送nil作为参数fromView将从视图的父窗口转换点(无论在哪里).您还可以发送任何其他视图以获取从该空间转换的坐标:

// convert from the window's coordinate system to the local coordinate system
NSPoint clickPoint = [self convertPoint:[theEvent locationInWindow] fromView:nil];

// convert from some other view's cooridinate system
NSPoint otherPoint = [self convertPoint:somePoint fromView:someSuperview];
Run Code Online (Sandbox Code Playgroud)