Как заставить курсор быть "arrowCursor", когда он наводит NSButton, который находится внутри NSTextView?

Хорошо, вот проблема:
у меня есть NSTextView и я добавляю свой обычай NSButton с помощью:

[_textView addSubview:button];

Тогда внутри моего NSButton подкласс, у меня есть (наряду с NSTrackingArea материал):

- (void)mouseEntered:(NSEvent *)event{
     [[NSCursor arrowCursor] set];
}

- (void)mouseExited:(NSEvent *)theEvent{
     [[NSCursor arrowCursor] set];
}

- (void)mouseDown:(NSEvent *)theEvent{
     [[NSCursor arrowCursor] set];
}

- (void)mouseUp:(NSEvent *)theEvent{
     [[NSCursor arrowCursor] set];
}

Но при наведении курсора курсор остается прежним IBeamCursor (потому что это NSTextView). Только когда я нажимаю кнопку, курсор обновляется. И затем, когда я двигаю мышь, все еще внутри кнопки, курсор возвращается к IBeamCursor,

Есть идеи, как это сделать? Спасибо!

1 ответ

Решение

Добавление области отслеживания, которая отслеживает только события входа / выхода, кажется недостаточным для NSTextView подвиды. Каким-то образом текстовое представление всегда побеждает и устанавливает его IBeamCursor,

Вы можете всегда пытаться включить отслеживание событий перемещения мыши (NSTrackingMouseMoved) при добавлении области отслеживания в ваш NSButton подкласс:

#import "SSWHoverButton.h"

@interface SSWHoverButton()
{
    NSTrackingArea* trackingArea;
}

@end

@implementation SSWHoverButton

- (void)mouseMoved:(NSEvent*)theEvent
{
    [[NSCursor arrowCursor] set];
}

- (void)updateTrackingAreas
{
    if(trackingArea != nil)
    {
        [self removeTrackingArea:trackingArea];
    }
    NSTrackingAreaOptions opts = (NSTrackingMouseMoved|NSTrackingActiveAlways);
    trackingArea = [[NSTrackingArea alloc] initWithRect:[self bounds]
                                                 options:opts
                                                   owner:self
                                                userInfo:nil];
    [self addTrackingArea:trackingArea];
}

- (void)dealloc
{
    [self removeTrackingArea:trackingArea];
}

@end

Вариант Swift 5:

import Cocoa

class InsideTextButton: NSButton {

    var trackingArea: NSTrackingArea?

    override func mouseMoved(with event: NSEvent) {
        NSCursor.arrow.set()
    }

    override func updateTrackingAreas() {
        if let area = trackingArea {
            removeTrackingArea(area)
        }

        trackingArea = NSTrackingArea(rect: self.bounds, options: [.mouseMoved, .activeAlways], owner: self, userInfo: nil)

        if let area = trackingArea {
            addTrackingArea(area)
        }
    }

    deinit {
        if let area = trackingArea {
            removeTrackingArea(area)
        }
    }
}
Другие вопросы по тегам