如何完成TableView选择和segue到下一个ViewController之间的功能?

发布于 2025-01-11 03:46:22 字数 2950 浏览 1 评论 0原文

我的应用程序具有以下流程:

  1. 视图控制器 1 呈现带有标题的 TableView
  2. 用户选择 TableView 行
  3. 视图控制器 1 指示模型加载所选 TableView 行的完整数据
  4. 模型将数据传递回视图控制器 1
  5. 视图控制器 1 将该数据传递给视图控制器 2作为 segue 的一部分

这就是我将数据传递到 View Controller 2 的方式:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        
        guard let destination = segue.destination as? UINavigationController else {
            return
        }
        
        guard let finalDestination = destination.viewControllers.first as? SegmentedControlViewController else {
            return
        }
        
        if let indexPath = tableView.indexPathForSelectedRow {
            
            let documentId = documentIdArray[indexPath.row]
            finalDestination.documentId = documentId
            print(documentID) // documentId is not nil and is passed to the next view controller successfully
            
            model.getRecipeSelected(docId: documentId) // the output of this is entireRecipe
            finalDestination.entireRecipe = entireRecipe
            print(entireRecipe) // entireRecipe is nil
        }
    }

应用程序崩溃,因为 View Controller 2 正在尝试处理尚不存在的数据。如何确保 model.getRecipeSelected(docId: documentId) 获取数据并将其传递给 View Controller 2 之前?

注意:我已确认将 model.getRecipeSelected(docId: documentId) 放入我的 viewDidLoad() 中可以正常工作。问题似乎是在转至视图控制器 2 之前,它尚未检索/传递数据。

编辑:我也尝试了以下操作,但没有成功。 >

<强>1。向我的模型添加了一个完成处理程序,并在准备函数中执行所有操作。

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        
        if segue.identifier == "MealPlanToSegmentedControl" {
            
            guard let destination = segue.destination as? UINavigationController else {
                return
            }

            guard let finalDestination = destination.viewControllers.first as? SegmentedControlViewController else {
                return
            }
            
            if let indexPath = tableView.indexPathForSelectedRow {
                
                let documentID = recipeDocIdArray[indexPath.row]
                finalDestination.passedDocID = documentID
                
                model.getRecipeSelected(docId: documentID) {
                    print("(entireRecipe)") // FIXME: SEGUE HAPPENS BEFORE entireRecipe IS ASSIGNED ANY DATA
                    finalDestination.entireRecipe = entireRecipe
                }
            }
        }
    }

2.向我的模型添加了一个完成处理程序并使用 didSelectRowAt

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        
        let documentID = recipeDocIdArray[indexPath.row]
        
        model.getRecipeSelected(docId: documentID) {
            self.performSegue(withIdentifier: "MealPlanToSegmentedControl", sender: Any?.self)
        }
    }

My app has the following flow:

  1. View Controller 1 presents TableView with Titles
  2. User selects TableView row
  3. View Controller 1 instructs Model to load the full data for that selected TableView row
  4. Model passes data back to View Controller 1
  5. View Controller 1 passes that data View Controller 2 as part of a segue

This is how I'm passing data to the View Controller 2:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        
        guard let destination = segue.destination as? UINavigationController else {
            return
        }
        
        guard let finalDestination = destination.viewControllers.first as? SegmentedControlViewController else {
            return
        }
        
        if let indexPath = tableView.indexPathForSelectedRow {
            
            let documentId = documentIdArray[indexPath.row]
            finalDestination.documentId = documentId
            print(documentID) // documentId is not nil and is passed to the next view controller successfully
            
            model.getRecipeSelected(docId: documentId) // the output of this is entireRecipe
            finalDestination.entireRecipe = entireRecipe
            print(entireRecipe) // entireRecipe is nil
        }
    }

The app crashes because View Controller 2 is trying to work off of data that isn't there yet. How can I make sure model.getRecipeSelected(docId: documentId) gets the data and passes it to View Controller 2 before I segue to it?

Note: I've confirmed that model.getRecipeSelected(docId: documentId) works by putting it in my viewDidLoad(). The issue seems to be that it hasn't retrieved/passed the data before the segue to View Controller 2.

Edit: I've also tried the following but with no success.

1. Added a completion handler to my model and do everything in prepare function.

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        
        if segue.identifier == "MealPlanToSegmentedControl" {
            
            guard let destination = segue.destination as? UINavigationController else {
                return
            }

            guard let finalDestination = destination.viewControllers.first as? SegmentedControlViewController else {
                return
            }
            
            if let indexPath = tableView.indexPathForSelectedRow {
                
                let documentID = recipeDocIdArray[indexPath.row]
                finalDestination.passedDocID = documentID
                
                model.getRecipeSelected(docId: documentID) {
                    print("(entireRecipe)") // FIXME: SEGUE HAPPENS BEFORE entireRecipe IS ASSIGNED ANY DATA
                    finalDestination.entireRecipe = entireRecipe
                }
            }
        }
    }

2. Added a completion handler to my model and use didSelectRowAt

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        
        let documentID = recipeDocIdArray[indexPath.row]
        
        model.getRecipeSelected(docId: documentID) {
            self.performSegue(withIdentifier: "MealPlanToSegmentedControl", sender: Any?.self)
        }
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

狼性发作 2025-01-18 03:46:22
  1. 在 VC1 中添加一个属性来存储您的配方
  2. 为 VC1 创建一个委托 didReceiveRecipe(recipe:) ,这将更新配方属性并将您的模型设置为 VC1 的委托。更新菜谱后,现在还调用 performSegue ,当您到达调用 prepare(for:sender:) 时,您肯定会拥有可用的菜谱。
  3. 在您的 didSelectRow 委托方法中,要求您的模型获取配方,这样做时将调用委托方法。
  1. Add a property in your VC1 that will store your recipe
  2. Create a delegate for your VC1 didReceiveRecipe(recipe:) which will update the recipe property and set your model as the delegate for VC1. After updating the recipe, also call performSegue now and when you reach the point of prepare(for:sender:) gets called, you will definitely have your recipe available.
  3. In your didSelectRow delegate method, ask your model to fetch the recipe which on doing so will call the delegate method.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文