Search code examples
objective-cmacoscocoanstableviewnsscrollview

NSTableView scrolling does not work


I have an issue with tableview scrolling.

I have dragged a scrollview in to the xib with the frame.

And I am creating a tableview programmatically and adding this to the scrollview as follows:

NSRect frame = [[ScrollView contentView] bounds];
rTableView = [[MTableView alloc] initWithFrame:frame];

MTableView is my custom class inheriting NSTableView and in the constructor, I am adding columns to the table view.

[ScrollView setDocumentView: resultsTableView];
[ScrollView setHasVerticalScroller:YES];
[ScrollView setHasHorizontalRuler:YES];

[rTableView setDelegate:self];
[rTableView setDataSource:self];
[ScrollView addSubview: rTableView];

[rTableView reloadData];

I have written the delegate functions to load the data and Table is being filled with the data. But the scroll does not work. I have 100 rows in the table and I am able to see the first 21 rows at the initial load of table view. And with the scroll nothing happens and the row index (that's in the data delegate) is always either 19 or 20. I am not sure what's going wrong here. I have seen some old posts in stackoverflow, followed the documentation of NSTableView but not of much help.

Any help is much appreciated.


Solution

  • You're doing everything right except for this line:

    [ScrollView addSubview: rTableView];
    

    A standard NSScrollView + NSTableView arrangement has the NSTableView set as the documentView of the NSScrollView. You've properly set up this relationship programmatically in your code:

    [ScrollView setDocumentView: resultsTableView];
    

    When you added the [ScrollView addSubview: rTableView] line, that added the table view in a way that wasn't intended. Basically, this addition only serves to prevent you from seeing the properly-scrolling table view that is beneath it.

    Removing that [ScrollView addSubview: rTableView] line should allow you to see the table view properly, and allow the scrolling mechanisms to work properly.

    An NSScrollView has numerous subviews that make up the scrolling architecture (see Scroll View Programming Guide for Mac). Examining the standard "NSTableView inside an NSScrollView" that's available in the Interface Builder palette shows that the scroll view has 4 immediate subviews:

    "<NSClipView: 0x103507200>",
    "<NSScroller: 0x101b14f80>",
    "<NSScroller: 0x101b15210>",
    "<NSClipView: 0x103507be0>"
    

    One of the clipviews holds the NSTableView and the other holds the NSTableHeaderView. Using NSScrollView's setDocumentView: in the line [ScrollView setDocumentView: resultsTableView] properly sets the table view to be the respective NSClipView's document view. On the other hand, adding the table view as a direct subview of the NSScrollView will cause the unexpected results you're seeing.