将文本附加到NSScrollView - 线程1:致命错误:在解包可选值时意外发现nil

时间:2017-11-27 21:59:45

标签: swift cocoa nsscrollview nsviewcontroller nspopover

我正在做一个Mac应用程序,当我从另一个类调用一个函数时,我在向NSScrollView附加文本时遇到了问题。

我在ViewController类上有这个功能:

import Cocoa

class PopoverVC1: NSViewController {

let popover1 = NSPopover()

class func loadView() ->PopoverVC1 {
    let vc = NSStoryboard(name: NSStoryboard.Name(rawValue: "Main"), 
bundle: nil).instantiateController(withIdentifier: 
NSStoryboard.SceneIdentifier(rawValue: "Popover1")) as! PopoverVC1
    vc.popover1.contentViewController = vc
    return vc
}

override func viewDidLoad() {
    super.viewDidLoad()

    popover1.behavior = .transient
    popover1.contentViewController = self
}

func showPopover (view: NSView){
popover1.show(relativeTo: view.bounds, of: view, preferredEdge: .maxY)

}

@IBOutlet weak var radioOption1: NSButton!
@IBOutlet weak var radioOption2: NSButton!
@IBOutlet weak var radioOption3: NSButton!


@IBAction func clickOption(_ sender: NSButton) {
    switch sender {
    case radioOption1: popover1.performClose(sender)

    case radioOption2: let vc = ViewController()
        vc.myPrint(string: "This is a test")

    default: print ("hello")

    }
}
}

我有一个PopoverVC1类,它是我正在使用的popover的类:

import Cocoa

class ViewController: NSViewController {


@IBOutlet weak var oneYes: NSButton!
@IBOutlet weak var oneNo: NSButton!
@IBOutlet weak var notesArea: NSScrollView!


override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.

}

override var representedObject: Any? {
    didSet {
    // Update the view, if already loaded
    }
}

func myPrint (string: String){
    let mystring = string
    let myNotes = notesArea.documentView as? NSTextView
    let text = myNotes?.textStorage!
    let attr = NSAttributedString(string: mystring)
    text?.append(attr)

}

let popover1 = NSPopover()
@IBAction func oneClicked(_ sender: NSButton) {


    switch sender {
    case oneYes: let vc = PopoverVC1.loadView()
        vc.showPopover(view: sender)

    case oneNo:
    let myNotes = notesArea.documentView as? NSTextView
    let text = myNotes?.textStorage!
    let attr = NSAttributedString(string: "test")
    text?.append(attr)

    default: print ("")
    }
}
}

然而,当我按下应该调用函数“myPrint”并传递参数的单选按钮“oneNo”时出现错误。

主题1:致命错误:在展开“可选”值时意外发现nil

我做了一些测试,当我在ViewCotroller类中调用同一个函数“myPrint”时,它工作正常。

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

当您致电时,问题出在clickOption

let vc = ViewController()
vc.myPrint(string: "This is a test")

当您从代码中调用此方法并在故事板中设置ViewController's UIViews时,不会创建与故事板的连接。这就是当您调用函数notesAreamyPrint为零的原因。在这种情况下,您正在创建ViewController的新副本,它与创建弹出窗口的副本不同。

有几种方法可以解决您要完成的问题。其中一个被称为delegate。这是一种方法,您可以调用ViewController's方法,例如popover继承它们。您可以查看教程here。我们的想法是,我们希望在ViewController中引用popover,以便您可以调用protocol中的函数。然后符合ViewController的{​​{1}}将负责处理方法调用。

因此,让我们创建一个名为protocol的{​​{1}},让您的protocol类符合它。然后在PrintableDelegate中,您可以将ViewController引用为popover ViewController(您可以使用您想要的名称,但{{1}是标准的)。然后我们可以通过编写weak var来调用协议delegate中描述的方法。我从我的示例中删除了一些不相关的代码。

delegate