我有一个ViewController
是使用Apple的新默认ModalTransitionStyle
呈现的。而且,如果取消了该ViewController
,则下面的ViewController
(具有TableView
)不会更新该表。
我尝试过ViewWill/DidAppear
,但是在两种情况下,尝试访问表时都出现错误 "Unexpectedly found nil while unwrapping an optional Value"
。
我检查了调用了哪些方法,发现numberOfRowsInSection
被调用而cellForRowAtIndexPath
没有被调用。该表肯定可见。它不是高度0,并且numberOfRowsInSection
不能返回0。
我做了一个快速测试项目,以证明我的意思。
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”是否正在增加。我只是不知道如何重新加载表。
答案 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值而导致崩溃。