我正在使用包含两个视图控制器:“TableViewController”和“EntryViewController”的NSSplitView与Swift OSX应用程序。我使用委托来传递一个自定义的NSObject(“Entry”),点击从TableViewController到SplitViewController,然后返回到EntryViewController。Swift OSX - 委托协议函数返回nil,解包文本域值时崩溃
我的问题是这样的:当在EntryViewController,收到任何企图其属性分配给文本字段值结果意外地发现零类型错误的的Entry对象,别提了IBOutlets是正确的链接,并且它既可以打印Entry.property 和文本字段值(只要它在不同的,不相关的函数中)。
我已经尝试了许多安排来解决这个问题,这就是为什么当前的配置可能有点过于复杂。直接从表VC到Entry VC的委托关系导致了相同的问题。
即使在委托调用之前加载了视图,IBOutlets是否还没有连接?我已经阅读了很多许多关于委托的文章(主要是针对iOS),但似乎无法找到我的问题的根源。我会第一个承认我对斯威夫特的把握有点零碎,所以我很乐意看到我试图做的只是简单的/黑客的编码,我应该尝试一些完全不同的东西。
感谢您的帮助!
TableViewController:
protocol SplitViewSelectionDelegate: class {
func sendSelection(_ entrySelection: NSObject)
}
class TableViewController: NSViewController {
@IBOutlet weak var searchField: NSSearchField!
@IBOutlet var tableArrayController: NSArrayController!
@IBOutlet weak var tableView: NSTableView!
var sendDelegate: SplitViewSelectionDelegate?
dynamic var dataArray = [Entry]()
// load array from .plist array of dictionaries
func getItems(){
let home = FileManager.default.homeDirectoryForCurrentUser
let path = "Documents/resources.plist"
let urlUse = home.appendingPathComponent(path)
let referenceArray = NSArray(contentsOf: urlUse)
dataArray = [Entry]()
for item in referenceArray! {
let headwordValue = (item as AnyObject).value(forKey: "headword") as! String
let defValue = (item as AnyObject).value(forKey: "definition") as! String
let notesValue = (item as AnyObject).value(forKey: "notes") as! String
dataArray.append(Entry(headword: headwordValue, definition: defValue, notes: notesValue))
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.sendDelegate = SplitViewController()
getItems()
print("TVC loaded")
// Do any additional setup after loading the view.
}
// send selection forward to entryviewcontroller
@IBAction func tableViewSelection(_ sender: Any) {
let index = tableArrayController.selectionIndex
let array = tableArrayController.arrangedObjects as! Array<Any>
let obj: Entry
let arraySize = array.count
if index <= arraySize {
obj = array[index] as! Entry
print(index)
print(obj)
sendDelegate?.sendSelection(obj)
}
else {
print("index unassigned")
}
}
}
SplitViewController:
protocol EntryViewSelectionDelegate: class {
func sendSecondSelection(_ entrySelection: NSObject)
}
class SplitViewController: NSSplitViewController, SplitViewSelectionDelegate {
var delegate: EntryViewSelectionDelegate?
@IBOutlet weak var mySplitView: NSSplitView!
var leftPane: NSViewController?
var contentView: NSViewController?
var entrySelectionObject: NSObject!
override func viewDidLoad() {
super.viewDidLoad()
// assign tableview and entryview as child view controllers
let story = self.storyboard
leftPane = story?.instantiateController(withIdentifier: "TableViewController") as! TableViewController?
contentView = story?.instantiateController(withIdentifier: "EntryViewController") as! EntryViewController?
self.addChildViewController(leftPane!)
self.addChildViewController(contentView!)
print("SVC loaded")
}
func sendSelection(_ entrySelection: NSObject) {
self.delegate = EntryViewController() //if this goes in viewDidLoad, then delegate is never called/assigned
entrySelectionObject = entrySelection
print("SVC:", entrySelectionObject!)
let obj = entrySelectionObject!
delegate?.sendSecondSelection(obj)
}
}
最后,EntryViewController:
class EntryViewController: NSViewController, EntryViewSelectionDelegate {
@IBOutlet weak var definitionField: NSTextField!
@IBOutlet weak var notesField: NSTextField!
@IBOutlet weak var entryField: NSTextField!
var entryObject: Entry!
override func viewDidLoad() {
super.viewDidLoad()
print("EVC loaded")
}
func sendSecondSelection(_ entrySelection: NSObject) {
self.entryObject = entrySelection as! Entry
print("EVC:", entryObject)
print(entryObject.headword)
// The Error gets thrown here:
entryField.stringValue = entryObject.headword
}
}
请注明答复是否能解决你的问题。 – Efren