How to make embedded view controller part of the responder chain?

ぃ、小莉子 提交于 2019-12-22 10:48:22

问题


I am developing a Mac app using storyboards. I have a window that presents an NSViewController as its contents, which contains a "container view controller" that embeds an NSSplitViewController.

The expected behaviour is for the NSSplitViewController to be part of the responder chain, such that a menu item that triggers the toggleSidebar action on the first responder actually collapses the item of the NSSplitViewController that's marked as a sidebar.

However, this simply does not happen and the menu item remains disabled. So my question is, how can-I get the NSSplitViewController to be part of the responder chain?


回答1:


Check out the nextReponsder property of NSResponder. This property defines the responder chain. It's normally set automatically to follow the responder change defined by the Cocoa framework, but you can alter it to insert/skip/divert the chain in a different direction.

For example, at some point (don't ask me when), Cocoa started including the window's controller in the responder chain. So that my apps work consistently on all versions of macOS, I'll include code like this my window's controller:

- (void)windowDidLoad
{
    // Sent when the controller's window has been loaded from the nib
    [super windowDidLoad];
    NSWindow* window = self.window;

    // Make sure this window controller is in the responder chain
    NSResponder* nextResponder = window.nextResponder;  // get our window's next responder
    if (nextResponder!=self)
        {
        // running earlier OS X that does not include the window controller in the chain: patch us in
        self.nextResponder = nextResponder;
        window.nextResponder = self;
        }

-windowDidLoad, -viewDidLoad, and -awakeFromNib are all good places to adjust the responder chain so they include, or exclude, whatever objects you want.




回答2:


I ended up getting this to work (in Swift 4) by adding my view controller to the window delegate. After that, my view controller was part of the responder chain (which made application menu items work in my view controller).

//Step 1: Add NSWindowDelegate to the controller
class MyViewController: NSViewController, NSWindowDelegate{
  override func viewDidLoad() {
    super.viewDidLoad()

    //Step 2: Add the view controller to the window delegate
    if let window = NSApp.windows.first{
      window.delegate = self
    }
  }
}

I hope that helps someone else. :)



来源:https://stackoverflow.com/questions/47914650/how-to-make-embedded-view-controller-part-of-the-responder-chain

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!