How to get contents of a NSTextFieldCell in a cell-based outline when the user quits while editing

44 views Asked by At

The previous version of this question was closed because the moderator did not recognize that this is a cell-based Outline not a view-based outline. The answer the moderator suggested does not work for a cell-based outline.

The question as previously asked was:

I have a cell-based NSOutlineView. How do I get the contents of the NSTextFieldCell when the user Quits the app while editing that cell. Currently, attributedStringValue returns the contents before editing began.

As requested in the comments, here is a NSViewController.h and .m . It references a storyboard with two outlets: outlineView and cellOutlet as shown in viewController.h.

ViewController.h

#import <Cocoa/Cocoa.h>

@interface ViewController : NSViewController <NSOutlineViewDataSource,NSOutlineViewDelegate, NSTextStorageDelegate, NSTextViewDelegate, NSWindowDelegate, NSTextFinderClient,NSTextFieldDelegate,NSSearchFieldDelegate>
@property (weak) IBOutlet NSOutlineView *outlineView;
@property (weak) IBOutlet NSTextFieldCell *cellOutlet;
@property(nonatomic,strong)NSMutableAttributedString* string;
@end

and ViewController.m

#import "ViewController.h"

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
}

-(void)viewWillAppear
{
    self.outlineView.dataSource = self;
    self.outlineView.delegate = self;
    self.outlineView.window.delegate = self;
    self.string = [[NSMutableAttributedString alloc] initWithString:@"TEST"];
}

- (void)setRepresentedObject:(id)representedObject {
    [super setRepresentedObject:representedObject];

}

-(BOOL)windowShouldClose:(NSWindow *)sender
{
    [self.view.window makeFirstResponder:nil];
    BOOL response = [sender makeFirstResponder:sender];
    NSMutableAttributedString* changedText = [[_cellOutlet attributedStringValue] mutableCopy];
    NSLog(@"On Quit value was: %@", changedText);
    return response;
}

-(id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item
{
    NSMutableAttributedString* string = [[NSMutableAttributedString alloc] initWithString:@"Outline Item"];
    return string;
}

-(BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item
{
    return NO;
}

- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
{
    {
        return _string;
    }
}

- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item
{
    if (!item)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

- (void)outlineView:(NSOutlineView *)outlineView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
{
    _string = object;
    NSLog(@"Changed Value:  %@",_string);
}
@end
1

There are 1 answers

2
Willeke On

Implement windowShouldClose in the window delegate class and call [window makeFirstResponder:nil].

- (BOOL)windowShouldClose:(NSWindow *)sender {
    return [sender makeFirstResponder:nil];
}

Implement applicationShouldTerminate in the application delegate class and test if the key window should close.

- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender {
    NSWindow *window = [sender keyWindow];
    if (![window.delegate windowShouldClose:window])
        return NSTerminateCancel;
    return NSTerminateNow;
}

Set "Application can be killed immediately when user is shutting down or logging out" to NO in info.plist.