2
votes

I am working on Xcode 6.1.1 on OSX 10.10.2

How do I make my table adjust its height, so that the height of table would always be equal to the sum of heights of all the rows.

In other words, it should not display any empty rows. And adding and deleting the rows would require NSTableView to resize it self.

Initially I was thinking of using following selection after addition and deletion of row.

[_tableViewHandle setFrameSize:(NSMakeSize(oldwidth, sumOfHeightOfAllRows)))]

But it looks like a hack.

Also can it be done using IB only ?

3

3 Answers

2
votes

Don't know if it may be done using IB only. In my case I use autolayout constraints and change its constant value.

  1. Add height-constraint to parent NSScrollView (may be disable scrolling).
  2. Connect the constraint to the outlet property.
  3. Use constant value when it's needed.
1
votes

It should work to constrain the table view to its superview (the clip view) with top and bottom constraints. You don't have to manually adjust the height or any constraint's constant. It should be automatic (the table view will size itself; that will force the clip view to be big enough to contain the table view; that will force the scroll view to be big enough to contain the clip view; etc.).

1
votes

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.