Eugene Gordin
Eugene Gordin

Reputation: 4107

How to make containing window/view resize as NSCollectionView gains or loses items?

In my OSX app I have a NSCollectionView. When I add more items than the view can fit, the view and window don't resize automatically to fit all the content.

How can I make it happen?

For example: I have a view that can fit 5 items to be visible. I add 3 more items and the view would extend to the right / bottom adding these 3 new items to the right / second row.

Any kind of help is highly appreciated.

Upvotes: 1

Views: 1040

Answers (1)

Ken Thomases
Ken Thomases

Reputation: 90641

There's no built-in support for this. Part of the reason is hinted at in your question:

… the view would extend to the right / bottom adding these 3 new items to the right / second row

Well, which would/should it do, extend to the right or extend down? There's no one correct response, so the collection view has no way to decide this on its own.

Basically, when you add or remove items, you will need to compute the desired size of the collection view and resize the containing view(s) and/or window to accommodate it.

The calculation would look something like this:

// This part only need to be done once
NSCollectionViewItem* collectionViewItem = [[[NSCollectionViewItem alloc] initWithNibName:@"IconViewItem" bundle:nil] autorelease];
NSSize itemSize = collectionViewItem.view.frame.size;

NSUInteger count = collectionView.content.count;
NSUInteger itemsPerRow;
if (count * itemSize.width < maximumDesiredWidth)
    itemsPerRow = count;
else
{
    itemsPerRow = floor(maximumDesiredWidth / itemSize.width);
    if (itemsPerRow == 0)
        itemsPerRow = 1;
}
NSUInteger rowsNeeded = (count + itemsPerRow - 1) / itemsPerRow;
if (!rowsNeeded)
    rowsNeeded = 1;
NSSize collectionViewSize = NSMakeSize(itemsPerRow * itemSize.width, rowsNeeded * itemSize.height);

NSSize scrollViewSize = [NSScrollView frameSizeForContentSize:collectionViewSize
                                      horizontalScrollerClass:nil
                                        verticalScrollerClass:nil
                                                   borderType:collectionView.enclosingScrollView.borderType
                                                  controlSize:NSRegularControlSize
                                                scrollerStyle:collectionView.enclosingScrollView.scrollerStyle];

Now you need to resize the scroll view to accommodate the collection view. And you may need to resize any containing views and the window. How you do that depends on whether you're using auto layout or not. If you're using auto layout, it further depends on exactly how you've set up the constraints.

If may be sufficient to compute the difference between scrollViewSize and collectionView.enclosingScrollView.frame.size and adjust the window's size by the same amount. Usually, you'd also adjust the window's origin, too, to keep the top of the window in the same place. That is, if you add N to the height of the window, you'd subtract N from the Y coordinate of the origin, too.

Upvotes: 2

Related Questions