简体   繁体   English

Swift-关闭视图控制器后不重新加载表视图数据

[英]Swift – Table view data not reloading after dismissing view controller

I have a view in my app called JournalViewController that I'm presenting over my PastSessionsViewController . 我在名为JournalViewController应用程序中有一个视图,该视图通过PastSessionsViewController呈现。 PastSessions has a table view that the user can tap to edit and bring up the journal. PastSessions具有一个表格视图,用户可以点击该表格视图来编辑和调出日记。

When the user edits an entry and saves it (saving to CoreData), dismissing JournalViewController I'd like for the table view in PastSessions to reflect those changes and show the updated table cell. 当用户编辑的条目并保存(保存到CoreData),驳回JournalViewController我想在表视图PastSessions ,以反映这些变化,并显示更新的表格单元格。

I'm calling tableView.reloadData() in PastSessionsViewController viewDidLoad() but that doesn't seem to be working. 我在PastSessionsViewController viewDidLoad()调用tableView.reloadData()PastSessionsViewController似乎不起作用。 I've also added a delegate for JournalViewController to interact with PastSessionsViewController ahead of dismissViewController 我还添加了一个委托JournalViewController与互动PastSessionsViewController提前dismissViewController

Here's some code to look at: 以下是一些代码:

In PastSessionsViewController : PastSessionsViewController

class PastSessionsViewController: UIViewController, UITableViewDelegate, JournalVCDelegate {
    weak var tableView: UITableView?
    weak var backButton: UIButton?

    let pastSessionsDataSource: PastSessionsDataSource

    init() {
        pastSessionsDataSource = PastSessionsDataSource()
        super.init(nibName: nil, bundle: nil)
    }

    required init(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        let tableView = UITableView()
        tableView.backgroundColor = nil
        tableView.delegate = self
        tableView.dataSource = pastSessionsDataSource
        tableView.registerClass(EntryCell.self, forCellReuseIdentifier: "cell")
        view.addSubview(tableView)
        self.tableView = tableView
    }

    override func viewDidAppear(animated: Bool) {
        tableView?.reloadData()
    }

    func didFinishJournalVC(controller: JournalViewController) {
        var newDataSource = PastSessionsDataSource()
        tableView?.dataSource = newDataSource
        // tried this ^, but it's causing the app to crash 

        // tableView?.reloadData() <- this isn't doing the trick either
        dismissViewControllerAnimated(true, completion: nil)
    }

    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        let editJournalVC = JournalViewController(label: "Edit your thoughts")
        editJournalVC.delegate = self

        presentViewController(editJournalVC, animated: true, completion: nil)
    }
}

In JournalViewController : JournalViewController

protocol JournalVCDelegate {
    func didFinishJournalVC(controller: JournalViewController)
}

class JournalViewController: UIViewController, UITextViewDelegate {
    var delegate: JournalVCDelegate! = nil

    func doneJournalEntry(sender: UIButton) {
        journalEntryTextArea?.resignFirstResponder()

        ... do some core data saving ...
        delegate.didFinishJournalVC(self)
    }
}

In PastSessionsDataSource : PastSessionsDataSource

   import UIKit
   import CoreData

   class PastSessionsDataSource: NSObject {
        var arrayOfEntries = [Entry]()
        var coreDataReturn: [Meditation]?

        func prepareEntries() {
          // gets stuff from coredata and formats it appropriately
        }

        override init() {
            super.init()
            prepareEntries()
        }
    }

    extension PastSessionsDataSource: UITableViewDataSource {
        func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return arrayOfEntries.count
        }

        func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! EntryCell

            ... set up the labels in the cell ...

            return cell
        }
    }

Thanks for looking! 感谢您的光临!

viewDidLoad is called when the view controller load its view at the first time, so basically it will only be called once during the view controller's whole life cycle. viewDidLoad在视图控制器第一次加载其视图时被调用,因此,基本上,它将仅在视图控制器的整个生命周期中被调用一次。
One quick solution is to put tableView.reloadData() in PastSessionsViewController viewWillAppear() or viewDidAppear() . 一种快速的解决方案是将tableView.reloadData()放在PastSessionsViewController viewWillAppear() or viewDidAppear()
However I do not like this quick solution as every time you dismiss JournalViewController , the table view will be reloaded, even the user has not changed anything on JournalViewController (for example, cancel the edit). 但是,我不喜欢这种快速解决方案,因为每次您关闭JournalViewController ,即使用户没有在JournalViewController进行任何更改(例如,取消编辑),表视图也会重新加载。 So I suggest to use delegate approach between PastSessionsViewController and JournalViewController , when the user actually edit the data on JournalViewController then inform PastSessionsViewController to refresh the table. 因此,我建议在用户实际在JournalViewController上编辑数据然后通知PastSessionsViewController刷新表时,在PastSessionsViewControllerJournalViewController之间使用委托方法。

You are currently prepare entries only on init of PastSessionsDataSource, but not after you did CoreData changes. 当前,您仅在PastSessionsDataSource的init上准备条目,但在更改CoreData之后不准备。 So each time when you reloadData for tableView you work with the same data set loaded initially. 因此,每次为tableView重新加载data时,都使用最初加载的相同数据集。 As a quick hack you can try to updated viewDidAppear in a following way: 作为快速攻克,您可以尝试通过以下方式更新viewDidAppear:

 override func viewDidAppear(animated: Bool) {
        if let tableView = tableView {
          let dataSource = tableView.dataSource! as PastSessionsDataSource
          dataSource.prepareEntries()
          tableView.reloadData()
        }
 }

Your tableView property is probably nil in viewDidAppear , based on your listed code. 根据列出的代码,您的tableView属性在viewDidAppear可能为nil The reason is that in viewDidLoad you construct a UITableView as tableView , and that is a local variable. 原因是在viewDidLoad您将UITableView构造为tableView ,这是一个局部变量。 You need to assign that variable to the property: 您需要将该变量分配给属性:

self.tableView = tableView

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM