2
votes

I have an NSSavePanel set up with an accessory view that contains a format popup menu and a tabless tabview with various options regarding the selected format. It shows up on the panel correctly, but I cannot seem to adjust its size.

Calling -setFrameSize on the accessoryView results in odd and incorrect resizing once, and then no response for any subsequent calls. Other controls in the view flat out refuse to respond to any calls at all.

Does NSSavePanel work like NSSearchField, which only uses its assigned menu as a template? If so, how can I manipulate the specific instance of the accessory view in the current active save panel?

1
It sounds like you are creating the accessoryView in code rather than a xib file. If so you might try the xib file approach. Also what do you mean by "uses its assigned menu as template"?Jim Merkel
No, the accessoryView is in my main xib file. As for the second bit, NSSearchFields use an NSMenu that you provide as a template and then use a copy of it at runtime, meaning one needs to modify the copy instead of the original.John Wells
Ok, but then why do you need to do a -setFrameSize in code? Isn't that already setup in the xib ?Jim Merkel
Because I need to be able to change the view's size to accommodate for format options (or the lack thereof). One format may have several options while another has none at all. If I just leave it at the view's largest potential size, there's going to be a sizable gap that will look awkward and unpolished when selecting no-option formats.John Wells

1 Answers

1
votes

My experience has been (especially with code that has to run on 10.5) that in order to handle permuting sizes in the accessoryView for NSSavePanel we had to remove (set it to nil) and re-add it. Under 10.7 (and, I believe, 10.6), it appears to be sufficient to call [savePanel layoutIfNecessary] after changing the frameSize.

In this case, since you mention that you are using invisible tab views. Usually a tab view has a consistent size. If you're looking to resize the NSSavePanel based on the contents of the various subviews, you may want to keep them as separate views (in the same or other NIB files) and load them as child views in the NSSavePanel.

I've successfully done this in a situation where the NIBs were dynamically loaded from an on-disk list of plug-in modules, where I used a single overall view that contained the popup menu and then I resized that view using -setFrameSize: in order to change it prior to adding the child view to it. Then I used addSubview: to add the subview to my existing view and called [savePanel layoutIfNecessary] after changing the size and adding the subview.

Here is the snippet of four adding the exportAccessoryViewController (this for us is what changes based on the selection of the popup menu) to our existing exportFormatOptionsView view (which contains the popup menu):

   NSSize currentSize = [exportFormatOptionsView bounds].size;
   NSView *newView = [exportAccessoryViewController view];
   NSSize newSize = NSMakeSize( currentSize.width, currentSize.height+[newView bounds].size.height);
   // resize the parent view
   [exportFormatOptionsView setFrameSize: newSize];
   // move the child view
   [exportFormatOptionsView addSubview: newView];

of course, when you switch these out dynamically, you need to make sure you change the view size of the intermediate view back to the original size, so you can add the supplementary view in later, which I did like this:

    NSSize currentSize = [exportFormatOptionsView bounds].size;
    NSView *oldView = [exportAccessoryViewController view];

    // pull it out
    [oldView removeFromSuperview];
    NSSize newSize = NSMakeSize( currentSize.width, currentSize.height-[oldView bounds].size.height);
    [exportFormatOptionsView setFrameSize: newSize];
    exportAccessoryViewController = nil;

Hope this helps.