【问题标题】:How to pass data from AppDelegate to ViewController after didSet?在 didSet 之后如何将数据从 AppDelegate 传递到 ViewController?
【发布时间】:2015-12-02 07:07:44
【问题描述】:

我创建了一个 os X 项目并使用 Main Menu 打开文件目录并在 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() 时,出现错误“致命错误:在展开可选值时意外发现 nil”。知道如何解决吗?

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

【问题讨论】:

  • 我可以从我的 AppDelegate.swift 中获取 filePath 并且 objects 不是零。但是,它无法更新我的 tableview。

标签: swift macos delegates parameter-passing nstableview


【解决方案1】:

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

在调用reloadData之前只需检查nil

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

顺便说一句,您可能也应该为self.objects 执行此操作。我猜self.objects 总是在self.fileTableView 之前初始化,因为它是之前声明的,但我不知道它是否记录在 Swift 规范中(如果知道这一点的人可以加入,我将不胜感激)。

【讨论】:

  • 您是否使用绑定来填充表格?如果没有,您是否实现了NSTableViewDataSource 中提供数据所需的其他方法?
  • 在进行上述任何操作之前,首先检查IBOutlet是否已正确连接...
【解决方案2】:
var vc = ViewController() 

它将在 AppDelegate 中创建另一个实例,显示 UI 实例将不会通过这种方式获取值传递。 我尝试使用 NSNotificationDelegate 方法,我的问题就解决了。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-05
    • 2021-01-17
    • 1970-01-01
    • 2010-12-11
    • 2020-10-01
    • 2017-02-22
    相关资源
    最近更新 更多