如何在didSet之后将数据从AppDelegate传递到ViewController?(How to pass data from AppDelegate to ViewController after didSet?)

我创建了一个os X项目并使用主菜单打开文件目录并在tableview上显示内容。

在我的AppDelegate.swift中:

class AppDelegate: NSObject, NSApplicationDelegate { var filePath: String = String() { didSet { // Pass filePath to ViewController } } @IBAction func openFile(sender: AnyObject) { let myOpenDialog = NSOpenPanel() myOpenDialog.canChooseDirectories = true if(myOpenDialog.runModal() != 0) { self.filePath = myOpenDialog.URL!.path! } }

我的ViewController.swift:

class ViewController: NSViewController, NSTableViewDataSource, NSTableViewDelegate { @IBOutlet weak var fileTableView: NSTableView! private var objects: NSMutableArray! = NSMutableArray() var fileDirectory: String = String() { didSet { showFileList(fileDirectory) } } func showFileList(fileDirectory: String) { var contentsInFolder: NSArray? var isDir : ObjCBool = false // Remove last loaded objects self.objects.removeAllObjects() if NSFileManager.defaultManager().fileExistsAtPath(fileDirectory, isDirectory:&isDir) { if isDir { contentsInFolder = try! NSFileManager.defaultManager().contentsOfDirectoryAtPath(fileDirectory) for id in contentsInFolder! { if ((id as! String).rangeOfString(".MOV") != nil) { self.objects.addObject(id) } } } } self.fileTableView.reloadData() } // MARK: - Table View func numberOfRowsInTableView(tableView: NSTableView) -> Int { return self.objects.count } }

当我在ViewController.swift中运行self.fileTableView.reloadData()时 ,我得到一个错误“致命错误:意外地发现零,同时展开一个可选值”。 任何想法如何解决它?

var vc = ViewController() var filePath: String = String() { didSet { vc.fileDirectory = filePath } }

I create an os X project and use Main Menu to open file directory and show the contents on tableview.

In my AppDelegate.swift:

class AppDelegate: NSObject, NSApplicationDelegate { var filePath: String = String() { didSet { // Pass filePath to ViewController } } @IBAction func openFile(sender: AnyObject) { let myOpenDialog = NSOpenPanel() myOpenDialog.canChooseDirectories = true if(myOpenDialog.runModal() != 0) { self.filePath = myOpenDialog.URL!.path! } }

My ViewController.swift:

class ViewController: NSViewController, NSTableViewDataSource, NSTableViewDelegate { @IBOutlet weak var fileTableView: NSTableView! private var objects: NSMutableArray! = NSMutableArray() var fileDirectory: String = String() { didSet { showFileList(fileDirectory) } } func showFileList(fileDirectory: String) { var contentsInFolder: NSArray? var isDir : ObjCBool = false // Remove last loaded objects self.objects.removeAllObjects() if NSFileManager.defaultManager().fileExistsAtPath(fileDirectory, isDirectory:&isDir) { if isDir { contentsInFolder = try! NSFileManager.defaultManager().contentsOfDirectoryAtPath(fileDirectory) for id in contentsInFolder! { if ((id as! String).rangeOfString(".MOV") != nil) { self.objects.addObject(id) } } } } self.fileTableView.reloadData() } // MARK: - Table View func numberOfRowsInTableView(tableView: NSTableView) -> Int { return self.objects.count } }

I got an error "fatal error: unexpectedly found nil while unwrapping an Optional value" when I run the self.fileTableView.reloadData() in ViewController.swift. Any idea how to fix it?

var vc = ViewController() var filePath: String = String() { didSet { vc.fileDirectory = filePath } }

最满意答案

当fileTableView作为ViewController的初始化过程的一部分被调用时, fileTableView和视图中的UITableView之间的连接尚未设置。 因此,执行self.fileTableView.reloadData()时它是nil 。

在调用reloadData之前,只需检查nil :

if(self.fileTableView != nil) self.fileTableView.reloadData()

在一个侧面说明中,您应该也可以为self.objects做这self.objects 。 我猜测self.objects总是在self.fileTableView之前被初始化,因为它之前被声明过了,但我不知道它是否是Swift规范中记录的行为(如果有人知道这个可以self.fileTableView将不会感激。

var vc = ViewController()

It will create another instance in AppDelegate and the display UI instance will not get the value pass via this way. I try to use NSNotification and Delegate method and my problem is solved.

AppDelegate.swift

var filePath: String = String() { didSet { NSNotificationCenter.defaultCenter().postNotificationName("refreshView", object: nil) } }

ViewController.swift

var fileDirectory: String = String() let delegate = NSApplication.sharedApplication().delegate as! AppDelegate override func viewDidLoad() { super.viewDidLoad() NSNotificationCenter.defaultCenter().addObserver(self, selector: "refreshView:", name: "refreshView", object: nil) } func refreshView(notification: NSNotification) { fileDirectory = delegate.filePath }

By doing so, I can get the filePath from my AppDelegate.swift

更多推荐