如何在 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() 时遇到错误 "fatal error: unexpectedly found nil while unwrapping an Optional value"。知道如何解决吗?
var vc = ViewController()
var filePath: String = String() {
didSet {
vc.fileDirectory = filePath
}
}
当 showFileList
作为 ViewController
初始化过程的一部分被调用时,fileTableView
和视图中的 UITableView
之间的连接尚未设置。所以执行self.fileTableView.reloadData()
的时候是nil
。
在调用 reloadData
之前简单地检查 nil
:
if(self.fileTableView != nil) self.fileTableView.reloadData()
附带说明一下,您可能也应该为 self.objects
执行此操作。我猜 self.objects
总是在 self.fileTableView
之前初始化,因为它是在之前声明的,但我不知道它是否在 Swift 规范中记录了行为(如果有人知道这个可以凑钱)。
var vc = ViewController()
它会在AppDelegate中创建另一个实例,显示UI实例将不会通过这种方式获取值传递。
我尝试使用 NSNotification 和 Delegate 方法,我的问题就解决了。
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
}
通过这样做,我可以从 AppDelegate.swift
中获取 filePath
我创建了一个 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() 时遇到错误 "fatal error: unexpectedly found nil while unwrapping an Optional value"。知道如何解决吗?
var vc = ViewController()
var filePath: String = String() {
didSet {
vc.fileDirectory = filePath
}
}
当 showFileList
作为 ViewController
初始化过程的一部分被调用时,fileTableView
和视图中的 UITableView
之间的连接尚未设置。所以执行self.fileTableView.reloadData()
的时候是nil
。
在调用 reloadData
之前简单地检查 nil
:
if(self.fileTableView != nil) self.fileTableView.reloadData()
附带说明一下,您可能也应该为 self.objects
执行此操作。我猜 self.objects
总是在 self.fileTableView
之前初始化,因为它是在之前声明的,但我不知道它是否在 Swift 规范中记录了行为(如果有人知道这个可以凑钱)。
var vc = ViewController()
它会在AppDelegate中创建另一个实例,显示UI实例将不会通过这种方式获取值传递。 我尝试使用 NSNotification 和 Delegate 方法,我的问题就解决了。
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
}
通过这样做,我可以从 AppDelegate.swift
中获取 filePath