Search code examples
objective-cmacosinterface-buildernstextfieldcocoa-bindings

Is there a way to update an NSTextField label's stringValue without using an outlet?


So I'm new to Cocoa and Objective-C programming, but I've read enough to be able to modify this one program I'm working on almost completely to my satisfaction...with the exception of one particular use case.

The program lets a user manually specify a path for where they want the files downloaded to reside, which is then saved into user defaults dictionary through binding the label's value to user defaults controller. The label's stringValue is then updated through the IBAction attached to the 'Open in Finder' button (by modifying the label outlet's stringValue inside the Push button's IBAction) which gets triggered whenever the user clicks the button and chooses a new path.

My problem is that when it comes time to download a file, if the path that the user has chosen no longer exists or is not valid, it will default to the user's desktop. But when this is the case, I do not see the desktop path being reflected in the label. This makes sense too, because there is no code to directly modify the label's stringValue in that case (no access to the label's outlet from that file). I've been trying to come up with a solution to fix this little thing that's been bugging me, but I haven't found a solution that's worked yet. Any advice or tips would be greatly welcome! I've included snippets of what the relevant pieces of my code look like below.

 "PreferencesController.m"
 - (IBAction)onOpenDownloadsPath:(id)sender {

    NSOpenPanel* panel = [NSOpenPanel openPanel];
    [panel setCanChooseFiles:NO];
    [panel setCanChooseDirectories:YES];
    [panel setAllowsMultipleSelection:NO];


    [panel beginWithCompletionHandler:^(NSInteger result){
        if (result == NSFileHandlingPanelOKButton) {
            NSURL*  theDir = [[panel URLs] objectAtIndex:0];
            NSString* thePath = theDir.path;
            [Preferences setDownloadsPath:thePath];
            self->_labelDisplay.stringValue = [Preferences getDownloadsPath];

         }

      }];}


    "Preferences.m"
    + (void)setDownloadsPath:(NSString *)value {

    NSUserDefaults* ud = [NSUserDefaults standardUserDefaults];
    [ud setObject:value forKey:@"Preferences.downloadsPath"];
}

    + (NSString*)getDownloadsPath {

        NSUserDefaults* ud = [NSUserDefaults standardUserDefaults];
        return [ud stringForKey:@"Preferences.downloadsPath"];
    }

Solution

  • Solved. I used an NSNotification observer/listener to listen for when the set function would get called, then updated the stringValue in the label accordingly.