NSWindowController/NSDocument lifecycle (closing)

1k views Asked by At

I have a 'standard' OS X document based app using NSWindowController, NSDocument etc. It has an NSTextView as part of its UI.

Question I have (and it's driving me nuts) is how best to trap 'Close Document' and then tell the NSTexView to finish edit.

Finishing the edit MAY result in the model being updated (and possibly the change count of the document) so I need to do this BEFORE all the other NSDocument logic decides whether a save is necessary.

Thanks

1

There are 1 answers

0
Marek H On

Your textview doesn't allow undo.

-(void)setAllowsUndo:(BOOL)value;

You either disabled it by calling former method or unchecked it in interface builder (for the textview). Without undo support in your textview your document isn't made dirty automatically (no updateChangeCount is made so document doesn't know it was edited).

Cleaner solution (without allowing undo):

To fix this you have to register as delegate and implement textDidChange: (NSTextViewDelegate method) or register for NSTextDidChangeNotification. Within those methods you can update your model AND/OR make document dirty/edited.

Alternatively:

When there is an attempt to close window/document catch one of those event. And resign responder. NSTextView will loose focus and update it's backing value.

[window makeFirstResponder:nil];

List of possible methods where to catch closing.

- (void)close;  //you have to call [super close]; 
- (BOOL)windowShouldClose:(NSWindow *)window;
- (void)canCloseDocumentWithDelegate:(id)delegate shouldCloseSelector:(SEL)shouldCloseSelector contextInfo:(void *)contextInfo;

NSTextViewDelegate inherits from NSTextDelegate

@protocol NSTextViewDelegate <NSTextDelegate>
@optional
@end

@protocol NSTextDelegate <NSObject>
@optional
- (BOOL)textShouldBeginEditing:(NSText *)textObject;        // YES means do it
- (BOOL)textShouldEndEditing:(NSText *)textObject;          // YES means do it
- (void)textDidBeginEditing:(NSNotification *)notification;
- (void)textDidEndEditing:(NSNotification *)notification;
- (void)textDidChange:(NSNotification *)notification;       // Any keyDown or paste which changes the contents causes this
@end