2

我正在使用自定义 NSCells 编写自定义 NSControl。它是一个控件,所以它必须响应鼠标。我在我的控件上创建了一个 NSTrackingArea,实现-mouseEntered:了. (而且我必须实现,但我不知道在那里做什么,所以现在我还没有覆盖这些方法。)在这些方法中,我成功地确定了鼠标当前位于哪个单元格上。现在我有两个问题:-mouseExited:-mouseMoved:-mouseUp/Down:

  • 这是跟踪鼠标的好方法吗?如果没有,我应该怎么做?
  • 当鼠标点击、鼠标进入单元格、鼠标离开单元格等时,我应该在我的 NSCell 上调用什么方法?苹果的文档对此不是很清楚。

所以,基本上:我应该什么时候调用我的 NSCell 上的什么方法来让它响应鼠标事件?

编辑:
重读文档,我想我应该调用 NSCell's和-trackMouse:inRect:ofView:untilMouseUp:override-startTrackingAt:inView:和. 还有两个问题:1)文档给人的印象是只有在鼠标按下时才会调用它们。那是对的吗?那我应该怎么做呢?2)我应该在哪里/什么时候打电话给 NSCell 的?-continueTracking:at:inView:-stopTracking:at:inView:mouseIsUp:-trackMouse:inRect:ofView:untilMouseUp:

4

1 回答 1

1

我最终实现了自己的鼠标跟踪机制:

// MyControl.m:

- (void)mouseDown:(NSEvent *)theEvent {
    int currentCellIndex = [self indexOfCellAtPoint:[self convertPoint:[theEvent locationInWindow] fromView:nil]];
    if (currentCellIndex < [cells count]) {
        MKListCell *cell = [cells objectAtIndex:currentCellIndex];
        currentCell = cell;
        [currentCell mouseDown:theEvent];
    }
}

- (void)mouseUp:(NSEvent *)theEvent {
    int currentCellIndex = [self indexOfCellAtPoint:[self convertPoint:[theEvent locationInWindow] fromView:nil]];
    if (currentCellIndex < [cells count]) {
        MKListCell *cell = [cells objectAtIndex:currentCellIndex];
        [cell mouseUp:theEvent];
    }
}

- (void)mouseEntered:(NSEvent *)theEvent {
    int currentCellIndex = [self indexOfCellAtPoint:[self convertPoint:[theEvent locationInWindow] fromView:nil]];
    if (currentCellIndex < [cells count]) {
        MKListCell *cell = [cells objectAtIndex:currentCellIndex];
        currentCell = cell;
        [currentCell mouseEntered:theEvent];
    }
}

- (void)mouseExited:(NSEvent *)theEvent {
    int currentCellIndex = [self indexOfCellAtPoint:[self convertPoint:[theEvent locationInWindow] fromView:nil]];
    if (currentCellIndex < [cells count]) {
        MKListCell *cell = [cells objectAtIndex:currentCellIndex];
        [cell mouseExited:theEvent];
        currentCell = nil;
    }
}

- (void)mouseMoved:(NSEvent *)theEvent {
    int currentCellIndex = [self indexOfCellAtPoint:[self convertPoint:[theEvent locationInWindow] fromView:nil]];
    MKListCell *cell;
    if (currentCellIndex < [cells count]) {
        cell = [cells objectAtIndex:currentCellIndex];
    }
    if (currentCell != cell) {
        [currentCell mouseExited:theEvent];
        [cell mouseEntered:theEvent];
        currentCell = cell;
    }
    else {
        [currentCell mouseMoved:theEvent];
    }
}

- (void)mouseDragged:(NSEvent *)theEvent {
    int currentCellIndex = [self indexOfCellAtPoint:[self convertPoint:[theEvent locationInWindow] fromView:nil]];
    MKListCell *cell = nil;
    if (currentCellIndex < [cells count]) {
        cell = [cells objectAtIndex:currentCellIndex];
    }
    if (currentCell != cell) {
        [currentCell mouseExited:theEvent];
        [cell mouseEntered:theEvent];
        currentCell = cell;
    }
    else {
        [currentCell mouseMoved:theEvent];
    }   
}

- (int)indexOfCellAtPoint:(NSPoint)p {
    int cellIndex = (self.bounds.size.height - p.y) / cellHeight;
    return cellIndex;
}

当然,在MyCell.h

- (void)mouseDown:(NSEvent *)event;
- (void)mouseUp:(NSEvent *)event;
- (void)mouseMoved:(NSEvent *)event;
- (void)mouseEntered:(NSEvent *)event;
- (void)mouseExited:(NSEvent *)event;

这些方法的实现为空(因此编译器不会抱怨,我可以将鼠标处理方法的实现留给子类)。

于 2013-03-31T13:25:52.783 回答