我显然正在设计一个拖放保管箱,它可以通过单击选择文件或将其拖放到文件上,我希望所选文件在下一个表格中可见对它。我的设计逻辑是,每当用户从NSOpenPanel
中选择文件时,它将选择的文件路径传递到CoreData
中,然后数组从CoreData
中一个接一个地检索它们,最后,请使用NSTableView
更新reloadData()
的内容。
基本上,我的问题是,每当我尝试从ViewController().getDroppedFiles()
类调用DropboxButton
时,总是得到一个Fatal error: unexpectedly found nil while unwrapping an optional value.
我的ViewController.swift:
import Cocoa
class ViewController: NSViewController, NSTableViewDataSource, NSTableViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
getDroppedFiles()
}
@IBOutlet weak var DroppedFilesTableView: NSTableView!
var droppedFiles: [DroppedFiles] = [] // Core Data class definition: DroppedFiles
func numberOfRows(in tableView: NSTableView) -> Int {
return droppedFiles.count
}
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
let droppedFilesCollection = droppedFiles[row]
if (tableView?.identifier)!.rawValue == "fileNameColumn" {
if let fileNameCell = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "fileNameCell")) as? NSTableCellView {
fileNameCell.textField?.stringValue = droppedFilesCollection.fileName!
return fileNameCell
}
} else if (tableView?.identifier)!.rawValue == "filePathColumn" {
if let filePathCell = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "filePathCell")) as? NSTableCellView {
filePathCell.textField?.stringValue = droppedFilesCollection.filePath!
return filePathCell
}
}
return nil
}
@IBAction func DropboxClicked(_ sender: NSButton) {
// selected file paths
for filePath in selectedFilePaths {
if let context = (NSApp.delegate as? AppDelegate)?.persistentContainer.viewContext {
let droppedFilesData = DroppedFiles(context: context)
droppedFilesData.fileName = getFileName(withPath: filePath)
droppedFilesData.filePath = filePath
do {
try context.save()
} catch {
print("Unable to save core data.")
}
}
getDroppedFiles()
}
}
func getDroppedFiles() {
if let context = (NSApp.delegate as? AppDelegate)?.persistentContainer.viewContext {
do {
try droppedFiles = context.fetch(DroppedFiles.fetchRequest())
} catch {
print("Unable to fetch core data.")
}
}
DroppedFilesTableView.reloadData() // Fatal Error: unexpectedly found nil while unwrapping an optional value (whenever I call this function in other class)
}
}
我使用按钮(NSButton
)作为保管箱(它具有自己的类),可以轻松单击该按钮并支持拖动选项。
我的DropboxButton.swift:
import Cocoa
class DropboxButton: NSButton {
required init?(coder: NSCoder) {
super.init(coder: coder)
registerForDraggedTypes([NSPasteboard.PasteboardType.URL, NSPasteboard.PasteboardType.fileURL])
}
override func draggingEntered(_ sender: NSDraggingInfo) -> NSDragOperation {
// some other codes
return .copy
}
override func draggingExited(_ sender: NSDraggingInfo?) {
// some other codes
}
override func draggingEnded(_ sender: NSDraggingInfo) {
// some other codes
}
override func performDragOperation(_ sender: NSDraggingInfo) -> Bool {
guard let pasteboard = sender.draggingPasteboard.propertyList(forType: NSPasteboard.PasteboardType(rawValue: "NSFilenamesPboardType")) as? NSArray,
let filePaths = pasteboard as? [String] else {
return false
}
for filePath in filePaths {
if let context = (NSApp.delegate as? AppDelegate)?.persistentContainer.viewContext {
let droppedFilesData = DroppedFiles(context: context)
droppedFilesData.fileName = getFileName(withPath: filePath)
droppedFilesData.filePath = filePath
do {
try context.save()
} catch {
print("Unable to save core data.")
}
}
ViewController().getDroppedFiles() // found nil with reloadData() in ViewController.swift
}
return true
}
}
因此,我如何reloadData()
从另一个类(DropboxButton: NSButton
)中获取ViewController类中的表视图,以便每当用户将文件拖放到保管箱中时,表视图就会重新加载?
P.S。要做到这一点对我来说意义重大,我真的需要在短时间内解决此问题,有人可以花一些时间来帮助我吗?
答案 0 :(得分:0)
您需要在getDroppedFiles()
的已加载实例上调用ViewController
。
使用ViewController().getDroppedFiles()
,您将创建一个ViewController
的新实例,该实例在任何地方都不会显示(因此,控件未初始化会导致nil错误)。
答案 1 :(得分:0)
我发现此解决方案对我的情况有用。
我使用观察者传递来自其他控制器类的数据和调用函数,现在我知道我正在创建一个未加载的ViewController
新实例。这是我的代码:
ViewController.swift:
class ViewController: NSViewController {
// other codes
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(getDroppedFiles), name: NSNotification.Name(rawValue: "reloadTableViewData"), object: nil)
}
@objc func getDroppedFiles() {
DroppedFilesTableView.reloadData()
}
}
DropboxButton.swift:
class DropboxButton: NSButton {
// other codes
override func performDragOperation(_ sender: NSDraggingInfo) -> Bool {
// other codes
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "reloadTableViewData"), object: nil)
return true
}
}
现在,一切正常,我什至可以添加一个userInfo:
在文件和类之间传递数据。