mirror of
https://github.com/cappuccino/cappuccino.git
synced 2026-09-13 22:21:29 +00:00
Merge pull request #3123 from daboe01/new-viewcontroller-responder-chain-issue
fixed: CPViewController doesn't participate fully in responder chain
This commit is contained in:
@@ -166,7 +166,7 @@ var CPViewControllerCachedCibs;
|
||||
|
||||
if (!cib)
|
||||
{
|
||||
// if the cib isn't cached yet : fetch it and cache it
|
||||
// if the cib isn't cached yet: fetch it and cache it
|
||||
cib = [[CPCib alloc] initWithCibNamed:_cibName bundle:_cibBundle];
|
||||
[CPViewControllerCachedCibs setObject:cib forKey:_cibName];
|
||||
}
|
||||
@@ -261,6 +261,11 @@ var CPViewControllerCachedCibs;
|
||||
if (_view == nil && [cibOwner isKindOfClass:[CPDocument class]])
|
||||
[self setView:[cibOwner valueForKey:@"view"]];
|
||||
|
||||
// If the view was just loaded, we must set its next responder.
|
||||
// This is the first half of inserting the controller into the responder chain.
|
||||
if (_view)
|
||||
[_view setNextResponder:self];
|
||||
|
||||
if (!_view)
|
||||
{
|
||||
var reason = [CPString stringWithFormat:@"View for %@ could not be loaded from Cib or no view specified. Override loadView to load the view manually.", self];
|
||||
@@ -408,12 +413,28 @@ var CPViewControllerCachedCibs;
|
||||
[self willChangeValueForKey:"isViewLoaded"];
|
||||
|
||||
_view = aView;
|
||||
|
||||
// When the view is set manually, we must set its next responder.
|
||||
if (_view)
|
||||
[_view setNextResponder:self];
|
||||
|
||||
_isViewLoaded = aView != nil;
|
||||
|
||||
if (willChangeIsViewLoaded)
|
||||
[self didChangeValueForKey:"isViewLoaded"];
|
||||
}
|
||||
|
||||
/*!
|
||||
@method nextResponder
|
||||
@discussion The CPViewController implementation of this method returns the superview
|
||||
of the view controller's view. This is the second half of the insertion,
|
||||
completing the chain: view -> viewController -> superview.
|
||||
*/
|
||||
- (id)nextResponder
|
||||
{
|
||||
return [_view superview];
|
||||
}
|
||||
|
||||
- (BOOL)automaticallyNotifiesObserversOfIsViewLoaded
|
||||
{
|
||||
return NO;
|
||||
@@ -465,6 +486,10 @@ var CPViewControllerViewKey = @"CPViewControllerViewKey",
|
||||
if (self)
|
||||
{
|
||||
_view = [aCoder decodeObjectForKey:CPViewControllerViewKey];
|
||||
// When the view is unarchived, we must also set its next responder.
|
||||
if (_view)
|
||||
[_view setNextResponder:self];
|
||||
|
||||
_title = [aCoder decodeObjectForKey:CPViewControllerTitleKey];
|
||||
_cibName = [aCoder decodeObjectForKey:CPViewControllerCibNameKey];
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
@import <AppKit/CPApplication.j>
|
||||
|
||||
var methodsCalled;
|
||||
var testResponderChainActionCalled;
|
||||
|
||||
@implementation CPViewControllerTest : OJTestCase
|
||||
{
|
||||
@@ -56,6 +57,28 @@ var methodsCalled;
|
||||
[self assert:expectedResult equals:methodsCalled];
|
||||
}
|
||||
|
||||
- (void)testResponderChain
|
||||
{
|
||||
testResponderChainActionCalled = NO;
|
||||
|
||||
// 1. Create the controller, its view, and a superview.
|
||||
var viewController = [[ResponderTestViewController alloc] initWithCibName:nil bundle:nil externalNameTable:@{}];
|
||||
var view = [viewController view];
|
||||
|
||||
// 2. Assert the responder chain is correctly wired.
|
||||
// The view's next responder should be its controller.
|
||||
[self assert:viewController equals:[view nextResponder] message:@"The view controller should be the next responder of its view."];
|
||||
|
||||
// 3. Test that an action sent to the view is handled by the controller.
|
||||
var wasHandled = [view tryToPerform:@selector(testAction:) with:nil];
|
||||
[self assertTrue:wasHandled message:@"The action should be handled by the responder chain."];
|
||||
[self assertTrue:testResponderChainActionCalled message:@"The view controller's action method should have been called."];
|
||||
|
||||
// 4. Test that the chain unwires correctly when the view is removed.
|
||||
[view removeFromSuperview];
|
||||
[self assert:nil equals:[viewController nextResponder] message:@"The next responder should be nil after the view is removed from its superview."];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation ViewController : CPViewController
|
||||
@@ -87,3 +110,14 @@ var methodsCalled;
|
||||
[methodsCalled addObject:_cmd];
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation ResponderTestViewController : CPViewController
|
||||
{
|
||||
}
|
||||
|
||||
- (void)testAction:(id)sender
|
||||
{
|
||||
testResponderChainActionCalled = YES;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user