我正在做一个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”时,它工作正常。
有什么想法吗?
答案 0 :(得分:1)
当您致电时,问题出在clickOption
:
let vc = ViewController()
vc.myPrint(string: "This is a test")
当您从代码中调用此方法并在故事板中设置ViewController's
UIViews
时,不会创建与故事板的连接。这就是当您调用函数notesArea
时myPrint
为零的原因。在这种情况下,您正在创建ViewController
的新副本,它与创建弹出窗口的副本不同。
有几种方法可以解决您要完成的问题。其中一个被称为delegate
。这是一种方法,您可以调用ViewController's
方法,例如popover
继承它们。您可以查看教程here。我们的想法是,我们希望在ViewController
中引用popover
,以便您可以调用protocol
中的函数。然后符合ViewController
的{{1}}将负责处理方法调用。
因此,让我们创建一个名为protocol
的{{1}},让您的protocol
类符合它。然后在PrintableDelegate
中,您可以将ViewController
引用为popover
ViewController
(您可以使用您想要的名称,但{{1}是标准的)。然后我们可以通过编写weak var
来调用协议delegate
中描述的方法。我从我的示例中删除了一些不相关的代码。
delegate