Search code examples
objective-cmacosnstableviewnsscrollview

Programmatically created NSTableView within NSScroll view cannot scroll horizontally


I am on macOS 10.16 (BigSur) XCode 12, objective-c.

I have create a NSTableView within an NSScroll View programmatically and filled it with dummy data. I CAN scroll down while i CANNOT scroll left and right. So i assume there's some misconfiguration in the code but i can't figure it out.

Here's the behaviour -as you can see theres more content on the right, but scrollbar doesn't scroll: enter image description here

And here's the code:

NSEdgeInsets insets = NSEdgeInsetsMake (0,0,0,0); // This is usually dynamic, just for demo purposes
NSEdgeInsets margins = NSEdgeInsetsMake (0,0,0,0); // This is usually dynamic, just for demo purposes

// Create tableView
NSTableView* tableView = [[NSTableView alloc] initWithFrame:NSZeroRect];
tableView.translatesAutoresizingMaskIntoConstraints = NO;
tableView.backgroundColor = [NSColor clearColor];
tableView.delegate = self.delegate ? self.delegate : weakSelf;
tableView.dataSource = self.delegate ? self.delegate : weakSelf;
tableView.rowHeight = [SHDataTableCellView height];
tableView.intercellSpacing = NSMakeSize(2, 2);
tableView.headerView = [[NSTableHeaderView alloc] initWithFrame:NSMakeRect(0, 0, 0, CGFLOAT_MIN)];
if (@available(macOS 11.0, *)) {tableView.style = NSTableViewStylePlain;}
self.tableView = tableView;

// Create Scroll View
NSScrollView* scrollView = [[NSScrollView alloc] initWithFrame:NSZeroRect];

// Setup scrollView
scrollView.drawsBackground = NO;
scrollView.hasVerticalScroller = YES;
scrollView.hasHorizontalScroller = YES;
scrollView.autohidesScrollers = NO;
scrollView.translatesAutoresizingMaskIntoConstraints = NO;
scrollView.documentView = tableView;    
scrollView.scrollerStyle = NSScrollerKnobStyleDefault;
scrollView.automaticallyAdjustsContentInsets = NO;
scrollView.contentInsets = insets;
scrollView.scrollerInsets = NSEdgeInsetsMake(-(insets.top), -(insets.left), -(insets.bottom), -(insets.right));    
self.scrollView = scrollView;

[self.view addSubview:scrollView];

// Add constraints
NSDictionary *viewBindings = NSDictionaryOfVariableBindings(view,scrollView);
NSDictionary *metrics = @{ @"marginLeft" : @(margins.left),
                           @"marginRight" : @(margins.right),
                           @"marginBottom" : @(margins.bottom),
                           @"marginTop" : @(margins.top),
                           @"insetLeft" : @(insets.left),
                           @"insetRight" : @(insets.right),
                           @"insetBottom" : @(insets.bottom),
                           @"insetTop" : @(insets.top)};

[view addConstraints: [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(marginLeft)-[scrollView]-(marginRight)-|" options:0 metrics:metrics views:viewBindings]];
[view addConstraints: [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(marginTop)-[scrollView]-(marginBottom)-|" options:0 metrics:metrics views:viewBindings]];

[scrollView addConstraint:[NSLayoutConstraint constraintWithItem:self.tableView
                                                 attribute:NSLayoutAttributeWidth
                                                 relatedBy:NSLayoutRelationEqual
                                                    toItem:scrollView
                                                 attribute:NSLayoutAttributeWidth
                                                multiplier:1.0
                                                  constant:0]];

[scrollView addConstraint:[NSLayoutConstraint constraintWithItem:scrollView
                                                 attribute:NSLayoutAttributeHeight
                                                 relatedBy:NSLayoutRelationEqual
                                                    toItem:nil
                                                 attribute:NSLayoutAttributeNotAnAttribute
                                                multiplier:1.0
                                                  constant:60]]; // equals 2 rows of content

NSEdgeInsets margin and insets are set to 0 in this example are tend to be used as dynamic variables (you may ignore them)


Solution

  • Removed the width constraint and it worked. Sometimes its just too obvious and you still don't see it.