展开后执行segue
Posted
技术标签:
【中文标题】展开后执行segue【英文标题】:Perform segue after unwinding 【发布时间】:2016-04-08 04:19:32 【问题描述】:我有一个包含在导航控制器中的主屏幕。
主屏幕有几个按钮可以触发到其他视图的 segues。一键进入表格视图。
此表中的选择应触发通常由主视图上的按钮之一执行的转场。
我假设我需要先展开到主屏幕,然后以编程方式从展开转场触发转场,但是当我这样做时,它会先执行程序转场,然后展开,最后再次出现在主屏幕上。
处理这种情况的正确方法是什么?我不想在以编程方式调用 segue 之后返回表格视图,然后返回按钮应该转到主视图。
如果它有助于进一步解释我的用例:表格视图是一个级别列表。选择应该启动我的游戏视图,并在表格视图中选择级别。
我在主视图中的放松转场:
@IBAction func backFromLevelSelectionUnwindSegue(segue:UIStoryboardSegue)
performSegueWithIdentifier("playSegue", sender: self)
显然playSegue
是游戏视图控制器的segue。
对类似问题的回答建议设置一个布尔标志,然后在 viewDidAppear 中执行转场,但 viewDidAppear 似乎不必知道已发生的展开转场。有没有我没有遇到过的“正确”解决方案?
【问题讨论】:
【参考方案1】:在您的 backFromLevelSelectionUnwindSegue 中,您仍处于 unwind segue 上下文中。因此,在使用 dispatch_async 或 performSelector:withObject:afterDelay 完成上下文后调用 performSegueWithIdentifier,如下所示。
@IBAction func
backFromLevelSelectionUnwindSegue( segue:UIStoryboardSegue )
dispatch_async( dispatch_get_main_queue() )
self.performSegueWithIdentifier( "playSegue", sender: self )
【讨论】:
【参考方案2】:您是否可以在不展开到主屏幕的情况下对游戏视图执行转场?那么当你展开segue时,将它展开到主视图而不是回到表格视图?如果我没记错的话,我们可以通过呈现视图控制器来放松。
【讨论】:
返回按钮将转到表视图而不是主视图【参考方案3】:这是一个见仁见智的问题,但在你的情况下,我认为你应该简单地在 tableview 和游戏之间设置一个 segue,任何必要的额外数据都从主 VC 传递给 tableview VC。
如果您需要返回 UINavigationVC 中的多个 viewController,我会考虑使用 popToRootViewController 或在它们之间使用 unWind。例如从第三个 viewController 调用 unwind,处理程序在第一个 viewController 中
【讨论】:
所以把表视图留在视图层次结构中并不少见?我必须说这似乎比让 viewDidLoad 执行 segue 更干净。 我认为以不同的方式来做这件事很好,但它似乎是一个很好的关注点组织。当你点击一行时,那个 VC 应该决定做什么。它不应该把它踢回它的父级。【参考方案4】:可以有多个返回不同位置的展开转场。在给定的场景中,应该安排视图控制器 Main->LevelSelect->Game
然后当游戏结束时,您有 2 或 3 个展开 segues 的按钮。第一个是exitToGameStart
,它允许玩家重新开始同一关卡。 exitToLevelSelect
允许玩家选择一个新的关卡。并且可选地exitToMainMenu
一直回到开始。有关完整示例,请参阅Apple's UnwindSegue sample,尤其是执行exitToQuizStart
unwind segue 的最后一个表上的“Start Over”按钮和执行exitToHomeScreen
unwind segue 的“返回到菜单屏幕”。接收方法代码如下:
QuestionViewController.m
//! Unwinds from the ResultsViewController back to the first
//! QuestionViewController when the user taps the 'Start Over' button.
//
// This is an unwind action. Note that the sender parameter is a
// 'UIStoryboardSegue*' instead of the usual 'id'. Like all unwind actions,
// this method is invoked early in the unwind process, before the visual
// transition. Note that the receiver of this method is the
// destinationViewController of the segue. Your view controller should use
// this callback to update its UI before it is redisplayed.
//
- (IBAction)exitToQuizStart:(UIStoryboardSegue *)sender
// The user has restarted the quiz.
[self.currentQuiz resetQuiz];
MainMenuViewController.m
//! Unwinds from the ResultsViewController back to the MainMenuViewController
//! when the user taps the 'Return to the Home Screen' button.
//
// This is an unwind action. Note that the sender parameter is a
// 'UIStoryboardSegue*' instead of the usual 'id'. Like all unwind actions,
// this method is invoked early in the unwind process, before the visual
// transition. Note that the receiver of this method is the
// destinationViewController of the segue. Your view controller should use
// this callback to retrieve information from the sourceViewController. Used
// properly, this method can replace existing delegation techniques for
// passing information from a detail view controller to a previous view
// controller in the navigation hierarchy.
//
- (IBAction)exitToHomeScreen:(UIStoryboardSegue *)unwindSegue
// Retrieve the score from the ResultsViewController and update the high
// score.
ResultsViewController *resultVC = (ResultsViewController*)unwindSegue.sourceViewController;
self.highScore = MAX(resultVC.currentQuiz.percentageScore, self.highScore);
注意:要在最新的 Xcode 中构建旧项目,请打开故事板、文件检查器、构建版本、选择更新的 ios 版本。
【讨论】:
以上是关于展开后执行segue的主要内容,如果未能解决你的问题,请参考以下文章