Re: VCs in the Responder Chain - Again, but with a good solution?
On 12 Feb 2014, at 00:49, Seth Willits wrote: > > This is one of those topics I thought about 6 years ago, came across a decent > easy-to-use solution that has worked fine so I've never really had to think > about it again. Until today. > > All the way back to when NSViewController was added it was clear that the VC > ideally should follow its view within the responder chain, and every once in > a while I see someone else's one off little hack, or > use-multiple-subclasses-and-call-some-code solution to put the VC next to the > view in the chain, but they're all overly complicated so I noodled on a new > idea. > > In this solution, all you need to do is have the view controllers you want to > be in the chain, descend from an NSViewController subclass. That's it. And > the implementation is really quite simple. The end result is each view's VC > is the view's nextResponder, and the VC's next responder is the view's > superview. So it just inserts itself in there nicely. > > The only possibility where I can see this being an issue is if something > _requires_ the view's nextResponder be its superview. Anybody know of a case > where that's what's required? > I hope not because this is by far the easiest solution I've seen (though it's > quite possible someone's already done exactly this). > > I'm optimistic, but braced for a bubble burst. > I think your bubble is reasonably okay. The implementation is simple and doesn’t require any direct responder chain manipulation. There are two options here, as you know: 1. Put the VC above the view on the chain. the VC’s next responder will be a view. 2. Chain the VCs above the window. the VC’s next responder will likely be a another VC. Which approach you use influences how you design and implement your action message flow. I use the 2nd approach at present - I can query a VC for its VC children and also target an action to just the VC chain, bypassing the views entirely. It is also sometimes useful to be able to pull VCs in and out of the responder chain at will. I think that approach 1 has a lot going for it but I find it conceptually cleaner to leave the view responder chain undisturbed and construct my VC chain after it. Jonathan ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
VCs in the Responder Chain - Again, but with a good solution?
This is one of those topics I thought about 6 years ago, came across a decent easy-to-use solution that has worked fine so I've never really had to think about it again. Until today. All the way back to when NSViewController was added it was clear that the VC ideally should follow its view within the responder chain, and every once in a while I see someone else's one off little hack, or use-multiple-subclasses-and-call-some-code solution to put the VC next to the view in the chain, but they're all overly complicated so I noodled on a new idea. In this solution, all you need to do is have the view controllers you want to be in the chain, descend from an NSViewController subclass. That's it. And the implementation is really quite simple. The end result is each view's VC is the view's nextResponder, and the VC's next responder is the view's superview. So it just inserts itself in there nicely. The only possibility where I can see this being an issue is if something _requires_ the view's nextResponder be its superview. Anybody know of a case where that's what's required? I hope not because this is by far the easiest solution I've seen (though it's quite possible someone's already done exactly this). I'm optimistic, but braced for a bubble burst. static int AGChainedViewControllerKVOContext; @implementation AGChainedViewController { // Need to avoid circular loadView/setView: nonsense, // so we're just keeping around our own ref in parallel. NSView * _theView; } - (void)dealloc; { if (_theView) { [_theView removeObserver:self forKeyPath:@"nextResponder" context:&AGChainedViewControllerKVOContext]; _theView.nextResponder = nil; [_theView release]; _theView = nil; } [super dealloc]; } - (void)setView:(NSView *)view; { if (_theView) { [_theView removeObserver:self forKeyPath:@"nextResponder" context:&AGChainedViewControllerKVOContext]; [_theView release]; _theView.nextResponder = nil; _theView = nil; } [super setView:view]; if (self.view) { _theView = [self.view retain]; [_theView addObserver:self forKeyPath:@"nextResponder" options:0 context:&AGChainedViewControllerKVOContext]; } } - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context; { if (context == &AGChainedViewControllerKVOContext) { if ((object == _theView) && [keyPath isEqual:@"nextResponder"]) { if (_theView.nextResponder) { if (_theView.nextResponder != self) { self.nextResponder = _theView.nextResponder; _theView.nextResponder = self; } } else { self.nextResponder = nil; } return; } } [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; } @end -- Seth Willits ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com