Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8922281
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 15, 20262026-06-15T06:47:36+00:00 2026-06-15T06:47:36+00:00

I have an app that resizes itself for different views using: NSSize currentSize =

  • 0

I have an app that resizes itself for different views using:

NSSize currentSize = [[box contentView] frame].size;
NSSize newSize = [v frame].size;
float deltaWidth = newSize.width - currentSize.width;
float deltaHeight = newSize.height - currentSize.height;
NSRect windowFrame = [w frame];
windowFrame.size.height += deltaHeight;
windowFrame.origin.y -= deltaHeight;
windowFrame.size.width += deltaWidth;

[box setContentView: nil];
[w setFrame: windowFrame
    display: YES
    animate: YES];

[box setContentView: v];

When you change the view, the window grows/shrinks based on the upper-left corner of the app. The app always starts on the first view, no matter which view the user was in when they quit, because this is a summary view. I also want it to be restorable so the last-used document is open on launch.

The problem: since most views are taller than the summary view, changing to one pushes the bottom left corner of the window farther down the screen. Now quit the app and relaunch, and the app positions the window to where that bottom left corner was previously. I know this is because that’s where Cocoa puts the origin, but it makes more sense for the user to have the window restart with the same top left corner, otherwise the app is shifting down the screen each time it’s opened.

I tried observing NSWindowWillCloseNotification and calling the above method again to reset the app to the summary view just before closing, but even though the code works, the window still starts in the wrong position – I’m guessing Cocoa sets an app’s restorable defaults before the notification is sent.

It’s been done before: System Preferences does it – it auto-resizes for views, dictates what your starting view is, but you can move the window and next time you open it, it’ll be in the new position based on the top left corner. Anyone have an idea how to emulate that?

Edit: Document.xib has a small window with a popup button and a box. The methods below change the views and resize the window to fit those views. Everything works fine while the app is open, the window shifting is only an issue when the app is closed and re-opened with an active document (ie. using Lion’s restore).

     ============================
    | Jump to:___                |    The "===" is the top and bottom edge of the window
    |                            |    The "___" is the pop-up menu for selecting the view
    | -------------------------- |    The dashed box on the inside is "box", which holds the views
    ||                          ||
    ||                          ||
    ||                          ||
    ||                          ||
    ||                          ||
    ||                          ||
    | -------------------------- |
     ============================
- (void)windowControllerDidLoadNib:(NSWindowController *)aController
{
    [super windowControllerDidLoadNib:aController];

    //Note that init creates the array viewControllers
    NSMenu *menu = [viewMenu menu];
    NSUInteger i, itemCount;
    itemCount = [viewControllers count];

    for (i = 0; i < itemCount; i++) {
        NSViewController *vc = [viewControllers objectAtIndex:i];
        NSMenuItem *mi = [[NSMenuItem alloc] initWithTitle: [vc title] action: @selector(changeViewController:) keyEquivalent:@""];
        [mi setTag: i];
        [menu addItem: mi];
    }

    [self displayViewController: [viewControllers objectAtIndex: 0]];
    [viewMenu selectItemAtIndex: 0];
}

- (void) displayViewController: (ManagingViewController *) vc {
    //End editing
    NSWindow *w = [box window];
    BOOL ended = [w makeFirstResponder:w];
    if (!ended) {
        NSBeep();
        return;
    }

    //Put view in box
    NSView *v = [vc view];

    NSSize currentSize = [[box contentView] frame].size;
    NSSize newSize = [v frame].size;
    float deltaWidth = newSize.width - currentSize.width;
    float deltaHeight = newSize.height - currentSize.height;
    NSRect windowFrame = [w frame];
    windowFrame.size.height += deltaHeight;
    windowFrame.origin.y -= deltaHeight;
    windowFrame.size.width += deltaWidth;

    [box setContentView: nil];
    [w setFrame: windowFrame display: YES animate: YES];

    [box setContentView: v];

}

- (IBAction)changeViewController:(id)sender {
    NSUInteger i = [sender tag];
    ManagingViewController *vc = [viewControllers objectAtIndex: i];
    [self displayViewController: vc];
}

I tried putting the first block of suggested code from @trudyscousin just below the for loop in -windowControllerDidLoadNib: and that anchored the window correctly, but when the code reaches -displayViewController: it sets currentSize = (6,6). I’m not sure if that’s because the box is empty in IB. It then adds the difference between (6,6) and the size of the SummaryView to the size of the window when the app last quit, making it huge.

I then tried using NSUserDefaults by adding two lines to -changeViewController:

NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setInteger: i forKey: @"lastViewController"];

and in -windowControllerDidLoadNib:

NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    if ([userDefaults integerForKey: @"lastViewController"]) {
        NSInteger i = [userDefaults integerForKey: @"lastViewController"];
        ManagingViewController *vc = [viewControllers objectAtIndex: i];
        NSView *v = [vc view];
        NSSize currentSize = [v frame].size;
        [box setFrameSize: currentSize];
        [self displayViewController: vc];
        [viewMenu selectItemAtIndex: i];
    } else {
        [self displayViewController: [viewControllers objectAtIndex: 0]];
        [viewMenu selectItemAtIndex: 0];
    }

This works, but forces the app to launch with the last used view, which wouldn’t be so bad except that it will even do that when a new document is opened/created. If I get rid of the else (i.e., always run those last 2 lines), I’m back to where I started – the app launches being shifted vertically down the screen. It looks like you can’t set the window’s origin at launch, or maybe it reloads its own defaults at a later point.

The last thing I did was go back to my starting code (not using the mask code provided by @trudyscousin) but at the bottom of -windowControllerDidLoadNib: I added:

[self performSelector: @selector(adjustOrigin) withObject: nil afterDelay:0.0f];

which calls:

- (void) adjustOrigin {
    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    if ([userDefaults integerForKey: @"lastViewController"]) {
        NSInteger i = [userDefaults integerForKey: @"lastViewController"];
        ManagingViewController *vc = [viewControllers objectAtIndex: i];
        NSView *v = [vc view];
        NSSize previousSize = [v frame].size;
        NSSize currentSize = [[[viewControllers objectAtIndex: 0] view] frame].size;
        CGFloat delta = previousSize.height - currentSize.height;
        NSRect windowFrame = [[box window] frame];
        windowFrame.origin.y += delta;
        [[box window] setFrame: windowFrame display:YES];
    }
}

That actually does work, but if multiple things are running, the lag is enough that you can see the window make the “jump” to its new origin, which is a little inelegant.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-15T06:47:37+00:00Added an answer on June 15, 2026 at 6:47 am

    Your code appears to be sound, but the real problem may be your document xib.

    If your document xib is set up for Auto Layout, turn that off. You can do that by selecting the file in Xcode. In the File inspector, turn off the “Use Auto Layout” check box.

    Once you’ve done that, select your popup button. In the Size inspector, anchor the button at the top and left side. Select your box. In the Size inspector, anchor the box on all four sides, and make sure it expands horizontally and vertically.

    To recap from my earlier answer, here’s your -windowControllerDidLoadNib: method with the changes I had suggested earlier:

    - (void)windowControllerDidLoadNib:(NSWindowController *)aController
    {
        [super windowControllerDidLoadNib:aController];
    
        //Note that init creates the array viewControllers
        NSMenu *menu = [viewMenu menu];
        NSUInteger i, itemCount;
        itemCount = [viewControllers count];
    
        for (i = 0; i < itemCount; i++) {
            NSViewController *vc = [viewControllers objectAtIndex:i];
            NSMenuItem *mi = [[NSMenuItem alloc] initWithTitle: [vc title] action: @selector(changeViewController:) keyEquivalent:@""];
            [mi setTag: i];
            [menu addItem: mi];
        }
    
        // ---
    
        NSWindow *myWindow = [[[self windowControllers] objectAtIndex:0] window];
    
        NSUInteger styleMask = [myWindow styleMask];
    
        styleMask ^= NSResizableWindowMask;
        [myWindow setStyleMask:styleMask];
    
        if ([myWindow setFrameUsingName:@"windowFrameAutosaveName"] == NO)
        {
            [myWindow center];
        }
    
        (void) [myWindow setFrameAutosaveName:@"windowFrameAutosaveName"];
    
        styleMask &= ~NSResizableWindowMask;
        [myWindow setStyleMask:styleMask];
    
        // ---
    
        [self displayViewController:[viewControllers objectAtIndex:0]];
        [viewMenu selectItemAtIndex:0];
    }
    

    I removed the older comments but now indicate where the additional code is. With this, you shouldn’t have to bother with maintaining your own defaults for the document, and you don’t have to bother with adjusting the origin.

    Put these two things together, and you (largely) have your fix.

    Yes, I needed to qualify that somewhat. Yours is a document-based application, and so you’re going to have to either come up with either a unique name under which to save your document’s window location in your user defaults, or perhaps a means of somehow storing that information with the document itself.

    As always, good luck to you in your endeavors.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm building an Android app that resizes based on the screen size using different
I have an asp.net MVC web app that processes images and resizes them which
I am trying to create a web app that will size itself to fill
have an app that finds your GPS location successfully, but I need to be
Have an app that has listings - think classified ads - and each listing
I have an app that switches between full screen and normal screen for a
I have an app that uses the ActionBar with tabs in combination with Fragments.
I have an app that lets the user interact with several forms. I can
I have an App that downloads and displays images from URL's. This works fine
I have an app that is part of a suite of related apps. It's

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.