NSCursor always resets to Arrow

If you don't want other views to change your cursor while dragging you can do in -mouseDown:

[[self window] disableCursorRects];

and in -mouseUp:

[[self window] enableCursorRects];
[[self window] resetCursorRects];

Try using the addCursorRect:cursor: to set the cursor for you view.

Override the resetCursorRects for your view:

- (void)resetCursorRects
{
    [super resetCursorRects];
    if(drag) {
        [self addCursorRect:self.bounds cursor:[NSCursor closedHandCursor]];
    }
}

You need to call invalidateCursorRectsForView: to force update your cursor rects:

[self.window invalidateCursorRectsForView:self];

But if you want to have different cursor outside of you view you can call [[NSCursor closedHandCursor] set] in your mouseDragged: method.


I had the same problem which was caused by the fact that during the drag I was modifying a subview's frame, which seems to reset the cursor. When adding the tracking area with the .cursorUpdate option and resetting the cursor inside cursorUpdate(with:), it seems to work correctly.

class MyViewController: NSViewController {

    var cursor: NSCursor?

    override func viewDidLoad() {
        super.viewDidLoad()
        view.addTrackingArea(NSTrackingArea(rect: .zero, options: [.activeInKeyWindow, .inVisibleRect, .cursorUpdate], owner: self))
    }

    override func mouseDown(with event: NSEvent) {
        cursor = NSCursor.closedHand
    }

    override func cursorUpdate(with event: NSEvent) {
        cursor?.set()
    }
        
    override func mouseUp(with event: NSEvent) {
        cursor = nil
    }
    
}