PerformSegue does not always go over, but cook (for: sender) is always called

My application does not always go to the next view controller when calling performSegue . However, it always does prepare(for:sender) immediately.

  • What are the reasons for performSegue not working without a tough error (and also execute prepareForSegue )?
  • Is there a specific state in which it is assumed that the source view controller is in what I need to check?
  • If I set a 10 second delay (via asyncAfter ), a crash will occur.

Scenario

I am trying to reassign a work segment for a new feature (integration into Spotlight search). The transition to my iPhone does not occur if the application remains in the detailed view. (The application has a UISplitViewController as its root view controller.)

However, the code works as expected when

  • I am testing my iPad - that is, when both basic and detailed views are displayed.
  • I test my iPhone when I leave the application on the main screen.

When I test my iPhone from the details screen {see code below}:

  • The details screen disappears (behind popToRootViewController )
  • The main view is displayed with the correct line highlighted (including NSLog saying "To master")
  • The function is executed, including prepare(for:sender) , but the detailed view is never displayed.

At this point, I can click on the appropriate line, and segue will execute as expected - this is tableView(:didSelectRowAt:) calls performSegue .

In more detail

Swift 3.0 and iOS 10

The application has a UISplitViewController as its rootViewController. The main view is a tableView with a list of recipes. The detailed view is a table listing the ingredients for the selected recipe. Going segue from selecting a recipe row to an ingredient table.

I am adding a new function: we put recipes in Spotlight so that the user can search for them, and when they are selected, the recipe is selected from the main view, and its ingredients are shown in a detailed view.

Now I'm trying to implement Spotlight search integration using appDelegate application(:continue:restorationHandler) :

 func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]?) -> Void) -> Bool { guard userActivity.activityType == CSSearchableItemActionType, let userInfo = userActivity.userInfo, let id = userInfo[CSSearchableItemActivityIdentifier] as? String else { return false } // The id is a unique identifier for recipe. if let inputRecipe = Recipe.getBy(uuid: id, moc: self.managedObjectContext) { let root = self.window?.rootViewController as! UISplitViewController let nav = root.viewControllers[0] as! UINavigationController // If this is a navigation controller, then detail is being shown if (nav.topViewController as? UINavigationController) != nil { NSLog("Should be a detail view") nav.popToRootViewController(animated: true) } if let masterVC = nav.topViewController as? RecipeMasterVC { NSLog("Into the master") masterVC.selectTableRowAt(recipe: inputRecipe) } } return true } 

Inside RecipeMasterVC I added this code to highlight

 func selectTableRowAt(recipe: Recipe){ let indexPath = self.fetchedResultsController.indexPath(forObject: recipe) self.tableView.selectRow(at: indexPath, animated: true, scrollPosition: .top) DispatchQueue.main.async { self.performSegue(withIdentifier: seguesEnum.RecipeDetail.rawValue, sender: recipe) } } 
+5
source share
1 answer

I have a similar scenario in my own application, not using segue, but still using split views. When I checked the code, I see that I had to add a delay of 200 ms to make it work. Never hit the root cause, but without a delay, even with asynchronous sending, it doesn’t work if the details screen is already displayed

+3
source

Source: https://habr.com/ru/post/1269131/


All Articles