-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathPARViewController.m
81 lines (66 loc) · 2.46 KB
/
PARViewController.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
// PARViewController
// Author: Charles Parnot
// Licensed under the terms of the BSD License, as specified in the file 'LICENSE-BSD.txt' included with this distribution
#import "PARViewController.h"
#import "PARObjectObserver.h"
// NSViewController base subclass that ensures automatic insertion into the responder chain
// this is achieved simply by doing KVO on the nextResponder value for the controlled view, encapsulated in the PARViewObserver helper class
@interface PARViewController()
@property (readwrite, retain) PARObjectObserver *nextResponderObserver;
@end
@implementation PARViewController
@synthesize nextResponderObserver;
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
self.nextResponderObserver = nil;
#if ! __has_feature(objc_arc)
[super dealloc];
#endif
}
- (void)patchResponderChain
{
// set the view controller in the middle of the responder chain
// to avoid recursion and responder chain cycle, make sure the controller is not already the next responder of the view
NSResponder *currentNextResponder = [[self view] nextResponder];
if (currentNextResponder != nil && currentNextResponder != self)
{
[self setNextResponder:currentNextResponder];
[[self view] setNextResponder:self];
}
}
- (void)setView:(NSView *)newView
{
[super setView:newView];
[self patchResponderChain];
[self.nextResponderObserver invalidate];
if (newView != nil)
self.nextResponderObserver = [PARObjectObserver observerWithDelegate:self selector:@selector(nextResponderDidChange) observedKeys:[NSArray arrayWithObject:@"nextResponder"] observedObject:[self view]];
// optionally observe the view frame
if ([self respondsToSelector:@selector(viewFrameDidChange)])
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSViewFrameDidChangeNotification object:nil];
if ([self view])
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(viewFrameDidChange:) name:NSViewFrameDidChangeNotification object:[self view]];
}
}
- (void)nextResponderDidChange
{
[self patchResponderChain];
}
//- (void)superviewDidChange
//{
// NSLog(@"new superview : %@", [[self view] superview]);
//}
- (void)viewFrameDidChange:(NSNotification *)aNotification
{
if ([self respondsToSelector:@selector(viewFrameDidChange)])
[self viewFrameDidChange];
}
- (IBAction)endEditing:(id)sender
{
NSWindow *window = [[self view] window];
if (window != nil && [window isKeyWindow] == YES)
[window makeFirstResponder:nil];
}
@end