取消上述ViewController后,UITableView不刷新

时间:2019-11-01 11:26:15

标签: ios swift uitableview

我有一个ViewController是使用Apple的新默认ModalTransitionStyle呈现的。而且,如果取消了该ViewController,则下面的ViewController(具有TableView)不会更新该表。

我尝试过ViewWill/DidAppear,但是在两种情况下,尝试访问表时都出现错误 "Unexpectedly found nil while unwrapping an optional Value"

我检查了调用了哪些方法,发现numberOfRowsInSection被调用而cellForRowAtIndexPath没有被调用。该表肯定可见。它不是高度0,并且numberOfRowsInSection不能返回0。

我做了一个快速测试项目,以证明我的意思。

Image when App Runs

When Popup button clicked

When i go back

import UIKit

var cells = 5

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {


    @IBOutlet weak var table: UITableView!

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return cells
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "test")

        return cell!
    }


    override func viewDidLoad() {
        super.viewDidLoad()
        table.reloadData()
        // Do any additional setup after loading the view.
    }

    @IBAction func popup(_ sender: Any) {
        performSegue(withIdentifier: "popover", sender: self)
    }


}

import UIKit

class PopoverViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        cells += 1
        // Do any additional setup after loading the view.
    }

    @IBAction func back(_ sender: Any) {
        let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(identifier: "vc") as! ViewController
        self.dismiss(animated: true)


    }

}

应该发生的是,每当我返回视图时,就会显示另外一个单元格。我检查了计数“ Cell”是否正在增加。我只是不知道如何重新加载表。

2 个答案:

答案 0 :(得分:0)

旧答案:

DispatchQueue.main.async { [weak self] in
  self?.table.reloadData()
}

新答案:

您的错误之一是

let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(identifier: "vc") as! ViewController

        self.dismiss(animated: true, completion: {
            vc.table.reloadData()
        })

vc不是您居住的主控制器,您必须发送居住控制器的参考。

顺便说一句。

class PopoverViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        cells += 1
        // Do any additional setup after loading the view.
    }

    @IBAction func back(_ sender: Any) {
        let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(identifier: "vc") as! ViewController

        self.dismiss(animated: true, completion: {
            vc.table.reloadData()
        })


    }

}

您的viewDidLoad方法应类似于:

override func viewDidLoad() {
        super.viewDidLoad()

        //table.reloadData()

        // Do any additional setup after loading the view.

        view.addSubview(table)
        table.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        table.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
        table.heightAnchor.constraint(equalTo: view.heightAnchor).isActive = true
        table.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true

        NotificationCenter.default.addObserver(self,
                                               selector: #selector(notify),
                                               name: .notifier,
                                               object: nil)


        self.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.action,
                                                                 target: self,
                                                                 action: #selector(hh))
    }

hh功能仅适用于programmatically当前Popover

@objc private func notify(notification: NSNotification){
        //do stuff using the userInfo property of the notification object
        print("notification has called")
        DispatchQueue.main.async {
            self.table.reloadData()
        }
    }


extension Notification.Name {
    static let notifier = Notification.Name("notifier")
}

并像这样更改您的cells变量:

var cells = 5{
    didSet{

        NotificationCenter.default.post(name: .notifier, object: nil)

    }
}

我已经为页面之间的消息传递创建了Notification模式。它为我工作。当您增加cells时,实例Notification已收到通知,并且单元格已更新。

答案 1 :(得分:0)

据我了解,ViewController是父母,PopoverViewController是孩子。孩子解雇后,父母应更新tableview。

viewDidLoad被父级调用一次,不会被解雇孩子。

因此,您可以为子视图控制器定义任何委托或闭包,这些代理或闭包将在父视图上重新加载tableview。您可以在解雇完成时称呼它。 dismiss(animated: Bool, completion: (() -> Void)?)

class PopoverViewController: UIViewController {

var onDismiss: (() -> Void)?
//...
}

// Also add this method to viewcontroller
class ViewController: UIViewController {

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier = "popover" {
            guard let popoverVC = segue.destination as? PopoverViewController else {
                return
            }
            popoverVC.onDismiss = { [unowned self] in
                self.tableView.reloadData()
            }
        }
    }

此外,您无需为解雇而创建父母。 let vc = UIStoryboard(name: "Main"..此行是不必要的。此新的vc不会显示,因此,如果尝试访问它,则会由于网点的nil值而导致崩溃。