macOS Swift主从代理/协议不起作用 [英] macOS Swift master-detail delegate/protocol not working

查看:159
本文介绍了macOS Swift主从代理/协议不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题一定很简单,但是我是新手。我有一个splitView,我试图将其作为主从关系进行管理。用户单击母版中的OutlineView项,这会触发需要更新详细信息侧上的PopUp按钮的内容的需求。我已尝试对较大的代码中的排列进行几次测试,然后从中提取以下代码(请参见下面的代码中标记的TEST 1,TEST 2,TEST 3,TEST4。失败的是TEST 3,并且由于displayListPopUP而失败在委托函数调用协议函数时,协议函数为nil,但是当类DetailViewController最初使用相同的指令加载PopUp时,协议函数为nil。如何修复测试3?

This question must be simple, but I am a newbie. I have a splitView that I am trying to manage as a Master-Detail relationship. The user clicks on an OutlineView item in the Master and that triggers a need to update the content of a PopUp button on the Detail side. I have tried several tests of the arrangement in the larger code from which the code below is extracted (See TEST 1, TEST 2, TEST 3, TEST 4 marked in the code below. The one that fails is TEST 3 and it fails because displayListPopUP is nil in the protocol function when it is called by the delegate although it is not nil when the class DetailViewController initially loads the PopUp with the same instructions. How do I repair TEST 3?

import Cocoa

var displayList: [String] = []

class MasterViewController: NSViewController {

    weak var delegate: detailViewControllerDelegate?
    let detailViewController = DetailViewController()

    override func viewDidLoad() {
        super.viewDidLoad()
        displayList = ["Problem(s) in Selected Category","EM3", "EM4"]        
        self.delegate = detailViewController as          detailViewControllerDelegate

    // TEST 1---THIS WORKS (Bingo is printed)
        delegate?.testPrint(val: "Bingo")
}

}

extension MasterViewController: NSOutlineViewDelegate {

    func outlineViewSelectionDidChange(_ notification: Notification){

        displayList = ["Problem(s) in Selected Category","EM1", "EM2"]

    // TEST 2---THIS WORKS (Bingo 2 is printed)
        delegate?.testPrint(val: "Bingo 2")

    // TEST 3---THIS DOESN'T WORK (displayListPopUP is nil)
        delegate?.loadListPopUP(list: displayList)
    }
}

protocol detailViewControllerDelegate: class {
    func testPrint(val: String)
    func loadListPopUP(list: [String])
}


class DetailViewController: NSViewController, detailViewControllerDelegate     {

//I CHECK, XCODE SAYS THIS OUTLET IS ACTIVE
    @IBOutlet weak var displayListPopUP: NSPopUpButton!

    override func viewDidLoad() {
        super.viewDidLoad()

    //TEST 4---THIS WORKS (PopUp button is loaded correctly)
        displayListPopUP.removeAllItems()
        displayListPopUP.addItems(withTitles: displayList)
    }

    func testPrint(val: String){
        print(val)
    }

    func loadListPopUP(list: [String]){
    //THIS DOES NOT WORK.  displayListPopUP is nil when called from delegate
        displayListPopUP.removeAllItems()
        displayListPopUP.addItems(withTitles: list)
    }

}

推荐答案

这似乎可以解决问题:

var detailViewController = DetailViewController()
weak var delegate: detailViewControllerDelegate?

override func viewDidLoad() {
    super.viewDidLoad()

...

detailViewController = 

self.storyboard?.instantiateController(withIdentifier: detailVC)as! NSViewController为! DetailViewController

self.storyboard?.instantiateController(withIdentifier: "detailVC") as! NSViewController as! DetailViewController

 // This is a trick to force the detailViewController to load its hierarchy     view, icluding displayListPopUP

    _ = detailViewController.view

...
}

... }

xcode确实显示了我的PopUp的有效出口。显然,macOS会通过其自己的视图实例来管理DetailViewController的初始显示。因此,测试4确实可以工作。

xcode does, indeed, show an active outlet to my PopUp. The initial display of DetailViewController is apparently managed by macOS with its own instantiation of the view. Thus Test 4 does work.

创建主从关系显然需要对我的DetailViewController进行新的实例化。由于我使用的是Storyboard,因此笔尖和笔尖(如果存在)是视线之外的,而且头脑不清。因此,@ OOper的实例化必须替换为所示的实例化。但是,他是正确的,实例化不会加载视图层次结构。到那时,测试3将失败,因为displayPopUP仍为nil。在第一次引用视图之后,将加载视图层次结构,并且所显示的虚拟调用将强制加载层次结构,并且displayPopUP现在处于活动状态。测试3现在成功。

Creating the master-detail relationship apparently requires a new instantiation of my DetailViewController. Since I am using Storyboard, nibs and xibs, if they exist, are out-of-sight and out-of-mind. Thus, @OOper's instantiation had to be replaced with the one shown. But, he is correct, the instantiation does not load the view hierarchy. At that point Test 3 would fail because displayPopUP would still be nil. The view hierarchy is loaded after the first reference to the view and the dummy call that is shown forces the hierarchy to load, with the displayPopUP now active. Test 3 is now successful.

这篇关于macOS Swift主从代理/协议不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆