2017-06-22 5 views
5

Meine App nicht immer zum nächsten View-Controller überleiten, wenn performSegue aufgerufen wird. Es führt jedoch immer die prepare(for:sender)sofort.performSegue nicht immer Übergang, aber vorbereiten (für: Absender) immer

  • Welche Gründe gibt es für eine performSegue nicht ohne arbeiten, um einen schwerwiegenden Fehler aufweist (und immer noch die prepareForSegue ausführen)?
  • Gibt es einen bestimmten Zustand, in dem der Quellansicht-Controller sein soll, in dem ich suchen muss?
  • Wenn ich eine 10 Sekunden Verzögerung (über asyncAfter) setze, tritt der Übergang auf.

Szenario

Ich versuche, ein Arbeits segue für ein neues Feature neu zu Zweck (Integration zu Spotlight-Suche.) Der Übergang nicht auf meinem iPhone nicht auftreten, wenn die Anwendung auf dem Detail bleibt Aussicht. (Die Anwendung hat einen UISplitViewController als Wurzel View-Controller).

jedoch der Code funktioniert wie erwartet, wenn

  1. ich auf iPad Test - das heißt, wenn sowohl die Master und Detailansichten dargestellt werden.
  2. Ich teste auf meinem iPhone, wenn ich die App auf der Masteransicht verlasse.

Wenn ich mein iPhone aus dem Detailbild testen {siehe Code unten}:

  1. Die Detailbild verschwindet (pro die popToRootViewController)
  2. Die Master-Ansicht angezeigt wird, mit der richtigen Zeile hervorgehoben (einschließlich der NSLog sagen "In den Master")
  3. Die Funktion ausgeführt wird, einschließlich der prepare(for:sender), aber die Detailansicht wird nie angezeigt.

An diesem Punkt kann ich die entsprechende Zeile tippen und das Segue wie erwartet auftritt - das ist tableView(:didSelectRowAt:) Anrufe performSegue.

noch mehr Details

Swift 3.0 & iOS 10

Die App hat einen UISplitViewController als RootViewController. Die Masteransicht ist eine TableView mit einer Liste von Rezepten. Die Detailansicht ist eine Tabelle, in der die Zutaten für das ausgewählte Rezept aufgelistet sind. Der Übergang wechselt von der Auswahl der Rezept-Zeile zu seiner Zutaten-Tabelle.

Ich füge ein neues Feature hinzu: die Rezepte in Spotlight zu setzen, so dass der Benutzer sie suchen kann und wenn ausgewählt, wird das Rezept aus der Masteransicht ausgewählt und seine Zutaten werden in der Detailansicht angezeigt.

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) 
    } 
} 
+0

Der Master-View-Controller wurde möglicherweise noch nicht geladen. Es ist durchaus möglich, dass der View-Controller existiert - das heißt, init() wurde aufgerufen, damit der Split-View-Controller darauf verweist, aber viewDidLoad() wurde nicht aufgerufen. Versuchen Sie, in viewDidLoad() etwas Debug-Code hinzuzufügen oder überprüfen Sie die isViewLoaded-Methode innerhalb von selectTableRow, um zu verfolgen, wann die Master-Ansicht tatsächlich geladen wird. – Dale

+0

@Dale - Direkt vor dem 'Dispatch {performSegue}' ist der Wert von 'self.isViewLoaded' wahr. – AgRizzo

+0

Ich habe ein ähnliches Szenario in meiner eigenen App, nicht mit segue, aber immer noch mit geteilten Ansichten. Als ich den Code überprüfte, sah ich, dass ich eine Verzögerung von 200ms hinzufügen musste, damit es funktionierte. Nie ging es um die Ursache, aber keine Verzögerung, selbst mit einem Versand async funktioniert nicht, wenn der Detailbildschirm bereits angezeigt wird – Dale

Antwort

3

Ich habe ein ähnliches Szenario segue in meinem

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 
} 

Im RecipeMasterVC, habe ich diesen Code:

Jetzt versuche ich, die Spotlight-Suche Integration über die AppDelegate der application(:continue:restorationHandler) zu implementieren eigene App, keine Verwendung von segue, aber immer noch Split-Ansichten verwenden. Als ich den Code überprüfte, sah ich, dass ich eine Verzögerung von 200ms hinzufügen musste, damit es funktionierte. Noch nie zur Grundursache, aber keine Verzögerung, auch bei einem Async-Versand funktioniert nicht, wenn der Detailbildschirm bereits angezeigt wird

Verwandte Themen