performSegue
が呼び出されたとき、私のアプリは必ずしも次のView Controllerにつながるとは限りません。ただし、常にprepare(for:sender)
を直ちに実行します。。performSegueは常に遷移するとは限りませんが、(送信者のために)常に呼び出されます
performSegue
はハードエラーがなくても動作するように(まだprepareForSegue
を実行する)ではないためにどのような理由がありますか?- ソースビューコントローラがチェックする必要があると思われる状態がありますか?
- (
asyncAfter
を介して)10秒の遅延を置くと、セグが発生します。
シナリオ
は、私は新しい機能のために働いてセグエ目的を再しようとしています(Spotlight検索に統合。)遷移が私のiPhone上で発生していないアプリが詳細に残っている場合ビュー。 (アプリは、そのルート・ビュー・コントローラとしてUISplitViewControllerを有する。)
ただし、コードは
- は私のiPadでテストしたときに期待どおりに動作する - すなわち、マスターおよび詳細の両方のビューが表示されているとき。
- 私は自分のiPhoneで、マスタービューにアプリを残してテストします。
Iは、詳細画面{以下のコードを参照}から自分のiPhoneをテストする:(popToRootViewController
あたり)詳細画面の消失
- (NSLogに「マスターに」と言っています)
prepare(for:sender)
を含む機能が実行されますが、詳細ビューは表示されません。この時点で
、Iは、適切な行をタップすることができ、そして予想通りセグエが発生 - それはtableView(:didSelectRowAt:)
コールperformSegue
あります。
さらに詳細
スウィフト3.0 & iOSの10
アプリはそのrootViewControllerとしてUISplitViewControllerを持っています。マスタービューは、レシピのリストを含むtableViewです。詳細ビューは、選択したレシピの成分をリストしたtableViewです。セグエは、レシピの行選択から原料テーブルに移行します。
レシピをSpotlightに入れてユーザーが検索できるようにし、選択するとレシピがマスタービューから選択され、その成分が詳細ビューに表示されます。
今、私はappDelegateのapplication(:continue:restorationHandler)
経由Spotlight検索の統合を実装しようとしています:
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
}
RecipeMasterVCの中で、私は私が私の中で同様のシナリオを持っている
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)
}
}
マスタービューコントローラがまだロードされていない可能性があります。ビューコントローラが存在することは完全に可能です。つまり、分割ビューコントローラがビューを参照するためにinit()が呼び出されましたが、viewDidLoad()は呼び出されていません。 viewDidLoad()にいくつかのデバッグコードを追加するか、selectTableRow内のisViewLoadedメソッドをチェックして、マスタービューが実際にロードされたときにトレースしてください。 – Dale
@Dale - 'Dispatch {performSegue}'の直前では、 'self.isViewLoaded'の値はtrueです。 – AgRizzo
私は自分のアプリで同様のシナリオを使用していますが、分割ビューを使用せずに分割ビューを使用しています。私がコードをチェックすると、それを動作させるために200msの遅延を加えなければならないことがわかりました。根本的な原因はありませんでしたが、遅延はありません。詳細画面がすでに表示されている場合、ディスパッチ非同期は機能しません。 – Dale