简体   繁体   English

UIViewController被关闭时重新加载TableView?

[英]Reloading TableView when a UIViewController is being dismissed?

The problem here is that I'm presenting EditCommentVC modally, over the current context of the CommentVC because I want to set the background of the UIView to semi-transparent. 这里的问题是,由于要将UIView的背景设置为半透明,因此我将在CommentVC的当前上下文上以EditCommentVC呈现EditCommentVC Now, on the EditCommentVC I have a UITextView that allows the user to edit their comment, along with 2 buttons - cancel (dismisses the EditCommentVC ) and update that updates the new comment and push it to the database. 现在,在EditCommentVC上,我有一个UITextView ,它允许用户编辑其注释以及2个按钮- cancel (关闭EditCommentVC )和update ,以更新新注释并将其推送到数据库。

In term of code, everything is working, except that once the new comment is being pushed and EditCommentVC is being dismissed, the UITableView on CommentsVC with all the comments is not being reloaded to show the updated comments. 在代码来看,一切正常,但一旦新评论正在推EditCommentVC被解雇,在UITableViewCommentsVC所有的意见没有被重新加载显示更新的意见。 Tried calling it from viewWillAppear() but it doesn't work. 试图从viewWillAppear()调用它,但是它不起作用。

How can I reload the data in the UITableView in this case? 在这种情况下,如何在UITableView中重新加载数据?

@IBAction func updateTapped(_ sender: UIButton) {
    guard let id = commentId else { return }
    Api.Comment.updateComment(forCommentId: id, updatedComment: editTextView.text!, onSuccess: {
        DispatchQueue.main.async {
            let commentVC = CommentVC()
            commentVC.tableView.reloadData()
            self.dismiss(animated: true, completion: nil)
        }
    }, onError: { error in
        SVProgressHUD.showError(withStatus: error)
    })

}

The code in the CommentVC where it transitions (and passes the id of the comment). CommentVC中的代码在其中转换(并传递注释的id )。 CommentVC conforms to a CommentActionProtocol that passes the id of that comment: CommentVC符合CommentActionProtocol ,后者传递了该注释的id

extension CommentVC: CommentActionProtocol {

    func presentActionSheet(for commentId: String) {
        let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
        let editAction = UIAlertAction(title: "Edit", style: .default) { _ in
            self.performSegue(withIdentifier: "CommentVCToEditComment", sender: commentId)
        }
        actionSheet.addAction(editAction)
        present(actionSheet, animated: true, completion: nil)

    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "CommentVCToEditComment" {
            let editCommentVC = segue.destination as! EditCommentVC
            let commentId = sender as! String
            editCommentVC.commentId = commentId
        }
    }

}

I see atleast 2 problems here: 我在这里看到至少2个问题

  1. You are creating a new CommentVC which you should not do if you want to update the tableView in the existing view controller. 您正在创建一个新的 CommentVC ,如果要在现有视图控制器中更新tableView ,则不应该这样做。

  2. Since you have mentioned that Api.Comment.updateComment is a an asynchronous call, you need to write the UI code to run on the main thread . 由于您已经提到Api.Comment.updateComment是一个异步调用,因此需要编写UI代码以在主线程上运行。

So first you need to have the instance of the commentVC in a variable inside this viewController. 因此,首先需要在该commentVC的变量中具有commentVC的实例。 You can store the instance of the view controller from where you are presenting this view controller. 您可以从显示此视图控制器的位置存储该视图控制器的实例。

class EditCommentVC {

    var commentVCdelegate: CommentVC!   
    // Rest of your code

}

Now you need to pass the reference commentVC in this variable when you are presenting the edit view controller. 现在,当您呈现编辑视图控制器时,需要在此变量中传递参考commentVC。

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "CommentVCToEditComment" {
        let editCommentVC = segue.destination as! EditCommentVC
        let commentId = sender as! String
        editCommentVC.commentId = commentId
        editCommentVC.commentVCdelegate = self
    }
}

Now you need to use this reference to reload your tableView. 现在,您需要使用此引用来重新加载tableView。

Api.Comment.updateComment(forCommentId: id, updatedComment: editTextView.text!, onSuccess: {
    DispatchQueue.main.async {
        commentVCdelegate.tableView.reloadData() // - this commentVC must be an instance that you store of the your commentVC that you created the first time
        self.dismiss(animated: true, completion: nil)
    }
}, onError: { error in
    SVProgressHUD.showError(withStatus: error)
})

Well, i had this problem too, and the solution i found was to use Protocol . 好吧,我也有这个问题,我发现的解决方案是使用Protocol I would recommend you to search how to send data back to previous ViewController . 我建议您搜索如何将数据发送回先前的ViewController That way, when you dismiss the EditCommentVC , you then send back a value(in my case i send true) to the previous ViewController(in your case, CommentVC), and then you'll have a function in CommentVC checking if the value is true and if it is, reload the TableView. 这样,当您关闭EditCommentVC ,您便将一个值(以我EditCommentVC ,我为true)发送回先前的 ViewController(以您为例,CommentVC),然后在CommentVC中有一个函数检查该值是否为如果为true,则重新加载TableView。

Here, let me show you an example of how i used (those are the names of my ViewControllers, functions and protocols, you can use whatever you want and send whatever data you want back): 在这里,让我向您展示一个使用方法的示例(这些是我的ViewControllers,函数和协议的名称,您可以使用所需的任何内容,也可以将所需的任何数据发送回去):

In your CommentVC , you'll have something like this: CommentVC中 ,您将具有以下内容:

protocol esconderBlurProtocol {
    func isEsconder(value: Bool)
}

class PalestranteVC: UIViewController,esconderBlurProtocol {

func isEsconder(value: Bool) {
        if(value){
        //here is where you can call your api again if you want and reload the data
            tableView.reloadData()
        }
    }

}

Also, dont forget that you have to set the delegate of EditCommentVC, so do it when you're presenting EditCommentVC, like this: 另外,不要忘记您必须设置EditCommentVC的委托,因此在呈现EditCommentVC时要这样做,如下所示:

let viewController = (self.storyboard?.instantiateViewController(withIdentifier: "DetalhePalestranteVC")) as! DetalhePalestranteVC
        viewController.modalPresentationStyle = .overFullScreen
        viewController.delegate = self
        self.present(viewController, animated: true, completion: nil)
//replace **DetalhePalestranteVC** with your **EditCommentVC**

And in your EditCommentVC you'll have something like this: 在您的EditCommentVC中,您将获得以下内容:

class DetalhePalestranteVC: UIViewController {

var delegate: esconderBlurProtocol?

override func viewWillDisappear(_ animated: Bool) {
        delegate?.isEsconder(value: true)
    }

}

That way, everything you dismiss EditCommentVC , you'll send back True and reload the tableView. 这样,您关闭EditCommentVC的所有内容都将发回True并重新加载tableView。

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

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