How to Make Embedded View Controller Part of the Responder Chain

Keep both NSSplitViewController's child controllers in first responder chain

Connect to First Responder.

You can have all child view controllers respond to actions by implementing -[NSResponder supplementalTargetForAction:sender:] in your NSSplitViewController subclass:

- (id)supplementalTargetForAction:(SEL)action sender:(id)sender
{
id target = [super supplementalTargetForAction:action sender:sender];

if (target != nil) {
return target;
}

for (NSViewController *childViewController in self.childViewControllers) {
target = [NSApp targetForAction:action to:childViewController from:sender];

if (![target respondsToSelector:action]) {
target = [target supplementalTargetForAction:action sender:sender];
}

if ([target respondsToSelector:action]) {
return target;
}
}

return nil;
}

Is it possible to insert NSObjectController to responder chain?

NSObjectController is a data-flow controller. Putting it in the responder chain does not make real sense.

However, you should read about the responder-chain for action messages. Doing so, you will prefer to put the action method into a window controller.

Where does my First Responder Chain start?

I found the solution to this problem. I just forgot to add a semicolon to my actions when I defined them in the First Responder.

SO I entered "delete" instead of "delete: " And just for this reason, my method -(void)delete:(id)sender was not called!

Thanks for your help anyway!

Responder Chain but NOT delegate property passes value back to view controller from container

The error in the question is where, in the conforming class, "an instance of PhotoCollectionVC() is created, and the delegate property set to self". In viewDidLoad, that just creates another instance with an irrelevant delegate property that will never be called. The delegate property of the actual embedded PhotoCollectionVC needs to be assigned to self - in order for the two VCs to communicate. This is done from within the prepareForSegue method:

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
{
...
let controller = (segue.destinationViewController as! PhotoCollectionVC)
...
controller.delegate = self
}
}
}

The rest of the example code is fine.

Here is a super simple example of delegation from an embedded container to its delegate VC. The embedded container simply tells the VC that a button has been pressed. The story board is just a VC with a container in it and a text outlet. In the container VC, there is just a button. And the segue has an identifier.

The code in the delegate ViewController is:

protocol ChangeLabelText: class
{
func changeText()
}

class ViewController: UIViewController, ChangeLabelText
{
@IBOutlet weak var myLabel: UILabel!

override func viewDidLoad()
{
super.viewDidLoad()
myLabel?.text = "Start"
}

func changeText()
{
myLabel?.text = "End"
}

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "feelTheBern"
{
let secondVC: myViewController = segue.destinationViewController as! myViewController
secondVC.delegate = self
}}
}

The code in the delegating View Controller, myViewController, is:

class myViewController: UIViewController
{
weak var delegate: ChangeLabelText?

@IBAction func myButton(sender: AnyObject)
{
print("action")
delegate?.changeText()
}

override func viewDidLoad() {
super.viewDidLoad()
}
}


Related Topics



Leave a reply



Submit