Search code examples
swiftmacoscocoanstableview

NSTableView and swift: How to select first row when pushing down arrow and last row is selected?


I have a very short question and couldn't find the answer by searching.

My program is a simple mac-program written in swift and cocoa. I use the NSTableView class and I want to navigate up and down through the rows by using the arrow keys. This works directly. But now I want that when the last row is selected and I hit the down key that the first row gets selected. It's like periodic boundary conditions ;)

Can you help me with this problem? Or tell me what I should read to handle such a problem?

Thank you very much :)


Solution

  • You can override keydown NSTableView. Don't forget to scroll once you do new selection.

    SWIFT:

    import Carbon.HIToolbox.Events
    
    class TableView : NSTableView {
    
        override func keyDown(with event: NSEvent) {
    
            if event.characters?.count == 1 {
                let character = event.keyCode
                switch (character) {
                case UInt16(kVK_UpArrow):
                    if selectedRow == 0 {
                        selectRowIndexes([numberOfRows - 1], byExtendingSelection: false)
                        scrollRowToVisible(numberOfRows - 1)
                        //scrollToEndOfDocument(nil)
                    } else {
                        super.keyDown(with: event)
                    }
                    break
                case UInt16(kVK_DownArrow):
                    if selectedRow == numberOfRows - 1 {
                        selectRowIndexes([0], byExtendingSelection: false)
                        scrollRowToVisible(0)
                        //scrollToBeginningOfDocument(nil)
                    } else {
                        super.keyDown(with: event)
                    }
                default:
                    super.keyDown(with: event)
                    break
                }
            } else {
                super.keyDown(with: event)
            }
        }
    }
    

    OBJECTIVE-C

    #import <Carbon/Carbon.h>
    @implementation TableView
    
    - (void)keyDown:(NSEvent *)event
    {
        if ([[event characters] length] == 1) {
            unichar code = [event keyCode];
            switch (code)
            {
                case kVK_UpArrow:
                {
                    if ([self selectedRow] == 0) {
                        [self selectRowIndexes:[NSIndexSet indexSetWithIndex:[self numberOfRows] - 1] byExtendingSelection:NO];
                        //[self scrollToEndOfDocument:nil];
                        [self scrollRowToVisible:[self numberOfRows] - 1];
                    } else {
                        [super keyDown:event];
                    }
                    break;
                }
                case kVK_DownArrow:
                {
                    if ([self selectedRow] == [self numberOfRows] - 1) {
                        [self selectRowIndexes:[NSIndexSet indexSetWithIndex:0] byExtendingSelection:NO];
                        //[self scrollToBeginningOfDocument:nil];
                        [self scrollRowToVisible:0];
                    } else {
                        [super keyDown:event];
                    }
                    break;
                }
                default:
                    [super keyDown:event]
                    break;
            }
        } else {
            [super keyDown:event];
        }
    }
    
    @end