在嵌入式视图控制器中执行一个函数

Execute a function in the embedded view controller

我有一个UIViewController。它有一个容器视图,其中嵌入了一个 UITableViewController

table 视图显示一个包含 20 个数字的数组。点击 Delete 按钮显示一个操作 sheet,它提供 2 个选项来修改上述数组。

我在UITableViewController里面有两个函数来修改数组。

class TableViewController: UITableViewController {

    fileprivate var values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    func deleteFirstTen() {
        values.removeSubrange(values.startIndex..<values.startIndex.advanced(by: 10))
        tableView.reloadData()
    }

    func deleteLastTen() {
        values.removeSubrange(values.startIndex.advanced(by: 10)..<values.endIndex)
        tableView.reloadData()
    }

    // MARK: - Table view data source
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return values.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
        cell.textLabel?.text = "\(values[indexPath.row])"
        return cell
    }
}

我初始化视图控制器并从 UIViewController 调用这些函数,但它什么也没做。

class ViewController: UIViewController {

    @IBAction func didTapDeleteButton(_ sender: UIBarButtonItem) {
        let tableViewController = storyboard?.instantiateViewController(withIdentifier: "TableViewController") as! TableViewController

        let sheet = UIAlertController(title: nil, message: "Do You Want to Delete...", preferredStyle: .actionSheet)
        sheet.addAction(UIAlertAction(title: "1 - 10", style: .default) { action in
            tableViewController.deleteFirstTen()
        })
        sheet.addAction(UIAlertAction(title: "11 - 20", style: .default) { action in
            tableViewController.deleteLastTen()
        })
        sheet.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
        present(sheet, animated: true, completion: nil)
    }

}

如何正确调用嵌入式视图控制器中的函数?

演示项目已上传here

根据您的示例项目,这是一个解决方案:

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    var tableViewController: TableViewController? = nil

    // this method is a point in which you can hook onto segues
    // coming from this viewController and do anything you want to
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // if it's a segue going to TableViewController and it has
        // the identifier we set in the storyboard, then this is the
        // tableViewController we want to get
        if segue.identifier == "embedSegue",
            let vc = segue.destination as? TableViewController {
            self.tableViewController = vc
        }
    }

    @IBAction func didTapDeleteButton(_ sender: UIBarButtonItem) {

        let sheet = UIAlertController(title: nil, message: "Do You Want to Delete...", preferredStyle: .actionSheet)
        sheet.addAction(UIAlertAction(title: "1 - 10", style: .default) { action in
            self.tableViewController?.deleteFirstTen()
        })
        sheet.addAction(UIAlertAction(title: "11 - 20", style: .default) { action in
            self.tableViewController?.deleteLastTen()
        })
        sheet.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
        present(sheet, animated: true, completion: nil)
    }

}

您想从情节提要中为您创建的转场中获取 tableViewControllerprepareForSegue:sender: 方法是一个点,您可以在其中挂钩从给定 viewController 到另一个的转场(即使它是嵌入转场)。检查上面的代码以获得有效的解决方案。

不要忘记为 segue 设置一个标识符(在我的例子中我使用了 "embedSegue",但使用对你有意义的任何东西)。在您的情况下,没有必要 - 您可以简单地测试 segue 是否转到 TableViewController 实例,但使用 segue 标识符是一个好习惯 - 当项目变大时它会得到回报。您可以通过单击 segue(从 ViewControllerTableViewController 的箭头)在故事板中设置它,在属性检查器的右侧面板上有一个标识符字段。