MASPreferences choose view

126 views Asked by At

I am using MASPreferences in my app, I was able to set up everything correctly, with 3 different views (preferences, login and about).What I would like to do is to choose which panel gets shown when the window is opened. This is so that when the user clicks on about, the about panel is shown, etc. instead of the last panel shown being the one displayed. As of now I have tried modifying the entry in the plist file, but it does not seem to work. Is there any other way?

2

There are 2 answers

0
ruben1691 On BEST ANSWER

So after a bit of trying, and by using @Jasper's answer, I came up with the following:

-(void)openPreferencesWindowWithIdentifier:(NSString *)identifier {
    [NSApp activateIgnoringOtherApps:YES];
    [[NSUserDefaults standardUserDefaults] setValue:identifier forKey:@"MASPreferences Selected Identifier View"];

    // Create the preferences window
    NSViewController *generalViewController = [[GeneralPreferencesViewController alloc]initWithNibName:@"GeneralPreferencesViewController" bundle:nil];
    NSViewController *loginViewController = [[PushoverLoginViewController alloc]initWithNibName:@"PushoverLoginViewController" bundle:nil];
    NSViewController *aboutViewController = [[AboutPreferencesViewController alloc]initWithNibName:@"AboutPreferencesViewController" bundle:nil];
    NSArray *controllers = [[NSArray alloc]initWithObjects:generalViewController,loginViewController,[NSNull null],aboutViewController, nil];
    NSString *windowTitle = NSLocalizedString(@"Preferences", @"Comon title for preferences window");
    _preferencesWindowController = [[MASPreferencesWindowController alloc]initWithViewControllers:controllers title:windowTitle];

    [self.preferencesWindowController showWindow:nil];
}

Essentially this method writes the required "tab" on the plist file, and then initalizes a new instance everytime. By doing so, the correct view is loaded. The identifier parameter is the one you set up for each of the views. Thanks again to Jasper for his answer, really helped me understand how to figure this one out!

1
Jasper On

MASPreferences remembers the last opened 'tab'

Change in the order in your array when passing it to your MASPreferencesWindowController should work to change the order of your tabs.

-(NSWindowController *)preferencesWindowController
{
    if (_preferencesWindowController == nil)
    {
        NSViewController *generalViewController = [[GeneralPreferencesViewController alloc] init];
        NSViewController *accountViewController = [[AccountPreferencesViewController alloc] init];
        NSViewController *troubleshootingViewController = [[TroubleShootingPreferencesViewController alloc] init];

        //Change the order here
        NSArray *controllers = [[NSArray alloc] initWithObjects:accountViewController, generalViewController, troubleshootingViewController, nil];

        NSString *title = NSLocalizedString(@"Preferences", @"Common title for Preferences window");
        _preferencesWindowController = [[MASPreferencesWindowController alloc] initWithViewControllers:controllers title:title];
    }
    return _preferencesWindowController;
}

Have a look inside MASPReferencesWindowController.m line 6. There is a static NSString key which handles the logic to show the last selected tab

static NSString *const kMASPreferencesSelectedViewKey = @"MASPreferences Selected Identifier View";

The key is used in:

- (void)windowDidLoad
{
    if ([self.title length] > 0)
        [[self window] setTitle:self.title];

    if ([self.viewControllers count])
        self.selectedViewController = [self viewControllerForIdentifier:[[NSUserDefaults standardUserDefaults] stringForKey:kMASPreferencesSelectedViewKey]] ?: [self firstViewController];

    NSString *origin = [[NSUserDefaults standardUserDefaults] stringForKey:kMASPreferencesFrameTopLeftKey];
    if (origin)
        [self.window setFrameTopLeftPoint:NSPointFromString(origin)];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowDidMove:)   name:NSWindowDidMoveNotification object:self.window];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowDidResize:) name:NSWindowDidResizeNotification object:self.window];
}

TL;DR

Look for the method - (void)setSelectedViewController:(NSViewController <MASPreferencesViewController> *)controller inside MASPreferencesWindowController.m

Comment this line:

// Record new selected controller in user defaults
[[NSUserDefaults standardUserDefaults] setObject:controller.identifier forKey:kMASPreferencesSelectedViewKey];

Now change the way you initialise your NSWindowController so you create a new instance every time, otherwise it will still remember the last selected tab:

-(NSWindowController *)preferencesWindowController
{
    NSViewController *generalViewController = [[GeneralPreferencesViewController alloc] init];
    NSViewController *accountViewController = [[AccountPreferencesViewController alloc] init];
    NSViewController *troubleshootingViewController = [[TroubleShootingPreferencesViewController alloc] init];
    //NSArray *controllers = [[NSArray alloc] initWithObjects:generalViewController, accountViewController, troubleshootingViewController, nil];
    NSArray *controllers = [[NSArray alloc] initWithObjects:accountViewController, generalViewController, troubleshootingViewController, nil];

    // To add a flexible space between General and Advanced preference panes insert [NSNull null]:
    //     NSArray *controllers = [[NSArray alloc] initWithObjects:generalViewController, [NSNull null], advancedViewController, nil];


    NSString *title = NSLocalizedString(@"Preferences", @"Common title for Preferences window");
    _preferencesWindowController = [[MASPreferencesWindowController alloc] initWithViewControllers:controllers title:title];

    return _preferencesWindowController;
}