0

I have a NSPopover window which contains a NSTableView. I want to remove empty row in the table view so I could use Auto Layout to make the popover window to fit the table view. Right now I have to assign a fixed size to the table view, which is not good because it will leave a lot of space in the window when there are few rows in the table view.

For iOS, the question and answer is Resizing UITableView to fit content. Unfortunately it does not apply to OS X.

Community
  • 1
  • 1
Rick
  • 331
  • 1
  • 4
  • 11

1 Answers1

0

An instance of NSTableView works differently to an instance of UITableView. Basically on OS X scrollable table views are an instance of NSScrollView that contains an instance of NSTableView as document view.

  • NSScrollView and NSClipView

These two classes aren’t part of the table view—nor are they required—but virtually all table views are displayed using the classes that make up the scroll view mechanism.

Apple Doc

This document view is clipped by a clip view ("The document area") of the scroll view, which is a subview of the scroll view itself.

Here you have a explanation of the scroll view hierarchy.

So the table view itself is a non-scrolling view, whose size is automatically adopted from its content (number of rows) – and everything you want and everything you need.

Therefore there are two ways to get your goal:

  • "Operate" the table view out of its hierarchy: Use a single table view without its parent views. This is not what you get in IB, when you put a table view in a window. You have to do that manually or to construct the table view in your code.

  • Resize the parental scroll view to the table view with autolayout.

I prefer the first approach, because I cannot see any reason to have a scroll view with a clip view around the table view, if there is nothing to scroll and clip. However, the second approach should work, too.

If you have questions, simply add it as comment.

Here is an example:

I made a video of it for better explanation

http://sendvid.com/0lu0tgda?secret=d7b751f9-a3e9-4cd1-9865-20884b0bd6c8

I put a "Tableview" (that means, what you get from IB, so it is a scroll view hierachy with a table inside) into a window and placed at at the left side. I did some bindings to get easy insert and remove. Just the usual stuff.

Then I have a method, replacing the scroll view with its table view:

- (IBAction)replaceView:(id)sender
{
  // Exchange the view
  NSView *contentView = self.scrollView.superview;
  NSTableView *tableView = self.tableView;

  [contentView addSubview:self.tableView];     // Isolate the table view and make it the new subview
  NSRect frame;
  frame.origin = self.scrollView.frame.origin; // Take the location from the scroll view
  frame.size = tableView.frame.size;           // Take the table views size
  tableView.frame = frame;
  [self.scrollView removeFromSuperview];       // Remove the meaningless scroll view
 
  // Size the window to the table view
  NSWindow *window = contentView.window;
  NSRect contentFrame = contentView.frame;
  contentFrame.size.height = frame.size.height;
  NSRect windowFrame = window.frame;
  windowFrame.size.height = [window frameRectForContentRect:contentFrame].size.height;
  [window setFrame:windowFrame display:YES];
   
  // Set constraints to make the window resizing, when table view resizes
  [contentView addConstraints:
  [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[tableView]|" options:0 metrics:nil  views:NSDictionaryOfVariableBindings(tableView)]];
}

Yeah, you can beautify that in many directions. However, it is just to demonstrate what you have to do and which tools to use.

Community
  • 1
  • 1
Amin Negm-Awad
  • 16,582
  • 3
  • 35
  • 50