故事板Xcode 6中的自适应segue。是否推式使用?

Xcode 6界面生成器默认有新的checkbox“使用大小类”。 它使视图适应。 在这里输入图像描述

当我尝试在故事板中的两个视图之间进行切换时,我有新的选项: 在这里输入图像描述

而不是老的:

在这里输入图像描述

现在我们有“显示”和“现在模态”而不是“推”和“模态”。 旧的选项被标记为已弃用。 我select了“show”选项,因为在segue设置中,它被称为“show(例如push)

在这里输入图像描述

但它不会推动。 Segueanimation看起来像从底部(模态)滑动和导航栏消失。

问题是:如何让“显示”工作像推? 是否可以或应该使用“推(弃用)”? 我在哪里可以find关于新types的赛格的任何信息? 我唯一在iOS8开发库中find的是故事板帮助您devise您的用户界面,但没有关于“show”segue的信息。

UPDATE

我试图创build新的项目,“显示”实际上是像“推”的作品。 我认为我的项目中的问题可能是因为我用导航控制器这样的代码,但我不知道如何解决它。

if ( [segue isKindOfClass: [SWRevealViewControllerSegue class]] ) { SWRevealViewControllerSegue *swSegue = (SWRevealViewControllerSegue*) segue; swSegue.performBlock = ^(SWRevealViewControllerSegue* rvc_segue, UIViewController* svc, UIViewController* dvc) { UINavigationController* navController = (UINavigationController*)self.revealViewController.frontViewController; [navController setViewControllers: @[dvc] animated: NO ]; [self.revealViewController setFrontViewPosition: FrontViewPositionLeft animated: YES]; }; } 

之后,我尝试在MainViewController之后推送NewViewController 在这里输入图像描述

更新2:

我似乎只有iOS 7,iOS 7.1的问题。

是的,使用“显示”而不是“推”

我怎样才能让“秀”工作像推? 是否可以或应该使用“推(depricated)”而不是?

这应该; 它为我做。 我正在使用Xcode 6 beta 2,并testing我使用单视图模板(调用IB'VC_A'中的预制视图控制器)。 然后我添加了另一个视图控制器('VC_B')。 然后我在VC_A上添加一个button来显示VC_B,另一个从VC_B返回到VC_A。 当我在故事板中添加一个导航控制器作为初始视图控制器并使VC_A成为rootViewController时,“push”和“show”都具有相同的效果。 如果我没有初始的导航控制器,并且使用'show',那么我得到你所描述的,VC_B从底部向上滑动。 如果我试图“推”我得到一个崩溃,因为为了做推我必须有导航控制器。 所以在显示导航控制器的情况下,'show'会显示出来,如果导航控制器不存在,那么会显示一个带有模式转换样式的显示。

我在哪里可以find关于新types的赛格的任何信息?

所以我在这里find了“界面生成器新增function”中的一些信息。 如果你看幻灯片,你会看到一张幻灯片(41)提到这个变化。 在观看会议video时,您可以跳到38分钟,他们开始讨论适应性赛段。 他们确实解释说,例如,在展示新的视图控制器时,“显示”自适应search会考虑上下文。

已经有一个被接受的答案,但是我想提供更多的信息,可能是以前没有的信息。

如前所述,“推”和“模态”阶段被弃用,分别被“放”和“现模”所取代。 根据苹果的文档,新的赛段已经进一步分成适应尺寸级别的赛段。 较旧的只能用于支持比iOS 8更早的iOS版本。

以下链接中的文档解释了所有可用的新旧版本的描述。

在故事板中的场景之间添加一个Segue

如果URL将来发生变化,这是每个新的segue的解释:

显示

根据屏幕内容在详细信息或主区域中显示内容。 如果应用程序正在显示主视图和详细视图,则将内容推送到详细信息区域。 如果应用程序仅显示主要或详细信息,则将内容推送到当前视图控制器堆栈的顶部。

显示细节

在详细区域中呈现内容。 如果应用程序正在显示主视图和详细视图,则新内容将replace当前的详细信息。 如果应用程序仅显示主或细节,则内容会replace当前视图控制器堆栈的顶部。

目前情况

以模态方式呈现内容。 有选项可以select演示文稿样式(UIModalPresentationStyle)和过渡样式(UIModalTransitionStyle)。

目前作为Popover

将内容呈现为锚定到现有视图的popup窗口。 有一个选项可以指定popup视图(UIPopoverArrowDirection)的一个边上显示的箭头的可能方向。 还有一个选项来指定锚点视图。

tldr; 从UIView / UIControl拖动到目标视图控制器,删除没有正确推送的Segue,并在故事板中重新创build它。

其他答案没有错,但是这个解释了正在发生的事情,如何validation它正在发生以及将来如何缓解这个问题。

背景

在我的情况下,即使我已经有一个UINavigationController作为我的初始视图控制器(与我的内容UIViewController,因为它的根),我的显示段没有工作。

为什么和如何显示接近破裂

Show segue在与storyboard的源xml中的segue相关联的动作中断开。 导致这种情况的典型情况可能是,如果您已经从之前在代码中调用的手动segue中重新定义了segue。 这在storyboard xml中留下了以下几点。

 <connections> <segue destination="85t-Z1-hxf" kind="show" identifier="ToOptions" action="showDetailViewController:sender:" id="gdZ-IX-KcN"> </connections> 

Nota Bene 将故事板视为xml; 右键单击故事板文件并select打开为>源代码 。 要恢复使用打开为>界面生成器 – 故事板

为了适应从故事板使用segue时的任何自定义操作,可以轻触进入prepareForSegue并拦截目标视图控制器,并调用该位置的任何方法。 在任何情况下,这个小错误的副作用(错误是这样的事实,当你重新定义segue它没有正确设置在xml〜即即使您更改segue从一个UIView(或UIControl)到目标视图控制器)。

不幸的是最直接的解决scheme失败 所以只需从Storyboard中删除动作的xml属性将不会解决问题。 相反,人们只需简单地删除和重新创build故事板中的segue

重新创build时,故事板xml将不再具有与特定的segue关联的操作,并且Show将作为Push执行。

示例Xml正确显示Segue

  <connections> <segue destination="RbV-Au-WV9" kind="show" identifier="ToOptions" id="5dm-os-bcS"/> </connections> 

减轻

为了防止再发生,只要可能通过使用prepareForSegue添加基于目标视图控制器的必要操作,就需要坚持非手动故事板。 或者,如果您必须混合搭配,请采取预防措施,以确认您的Show segues在storyboard xml中没有附加任何操作。 如果您正在处理较旧的项目,那么您应该特别注意Storyboard源代码,因为我发现了一些问题。

正如Scott Robertson在这里评论的 ,这看起来像是iOS 7中的一个bug。

看起来,在iOS 8中,转换是在运行时推断的(正确行为),而在iOS 7中则是在devise时推断转换(buggy行为)。

最简单的解决方法是将一个未使用的导航控制器添加到故事板并将其链接起来,以便所讨论的视图控制器是此导航控制器的一部分。 您实际上并不需要实例化导航控制器,只需要使用错误的视图控制器就可以知道它被embedded在导航控制器中。

注意:模拟导航栏不足以满足这些目的; 您必须在其推送栈中实际上有一个导航控制器。

重现错误:

  1. 创build一个使用大小类的新故事板。
  2. 创build一个两个视图控制器(没有导航控制器)。
  3. 例如,使第一个视图控制器通过链接到button的Show(例如Push) segue 显示第二个视图控制器。
  4. 在代码中,显示第一个视图控制器,但通过initWithRootViewController:方法将其embedded到导航控制器中。
  5. 在iOS 7上运行应用程序。
  6. 点击应该执行button的button。
  7. 您将获得模式转换,而不是在iOS 7上进行推送。在iOS 8上,您将获得正确的推送行为。

在这里输入图像描述

修复这个bug:

  1. 将导航控制器添加到故事板,并将第一个视图控制器设置为根视图控制器。 (注意:添加第二个作为根视图控制器不会修复这个bug。)
  2. 给它一个垃圾标识符来抑制关于导航控制器不可访问的警告,并将自己logging为仅作为解决方法存在。 (例如workaround for show segues in iOS 7 )。

在这里输入图像描述

注意导航控制器是如何在第二张图片中添加的,以及它如何没有任何传入的箭头(即除了使用其视图控制器标识符之外,没有办法实例化它)。

我知道我迟到了,但我想分享我学到的东西。 这实际上是一个错误,今天仍然存在(2014-12-18)。

我在这里写了一篇关于这个的文章。

它很容易重现; 在iOS8上将工作得很好,甚至在iOS7.x,只要你不调用视图控制器编程到堆栈之前调用Show segue。

如果你只是使用故事板连接推到堆栈,它将工作; 但显然,如果你通过代码推某种方式推UIViewControllernavigationController属性将nil ,当你调用Show它将假设其模式,因为没有导航来控制堆栈。

目前只有解决方法是不通过代码推送(不可行)或使用现在弃用的Push

我提交了一个雷达(文章链接)。 随意与苹果解决这个问题的希望文件重复。

我在Xcode 7和iOS 7.1.2中遇到了同样的问题。 显示segues(iOS 8中的新function) 在iOS 7中的工作方式类似于模式细分,当您在Storyboard中使用Xcode定义细分types时,不允许将视图控制器推入导航控制器堆栈。 这就是为什么你的self.navigationController将返回零,因为视图控制器没有推到堆栈,你不能popup它。

我不明白为什么苹果没有在Xcode中为这种情况添加任何通知,当你需要你的应用程序在iOS 7上工作。 他们说,Push方法是不赞成的,但Show不能正常使用iOS 7。

我做了什么来解决这个问题:

我用.h创build了MYShowSegue类

 #import <UIKit/UIKit.h> @interface MYShowSegue : UIStoryboardSegue @end 

和.m文件只有一个执行方法:

 #import "MYShowSegue.h" @implementation MYShowSegue - (void) perform { if ([[[self sourceViewController] navigationController] respondsToSelector:@selector(showViewController:sender:)]) { id sender = nil; [[[self sourceViewController] navigationController] showViewController:[self destinationViewController] sender:sender]; }else{ [[[self sourceViewController] navigationController] pushViewController:[self destinationViewController] animated:YES]; } } @end 

比你需要为Storyboard中的每个Segue设置一个Customtypes,并为它select一个新的类,在我的情况下,它是MYShowSegue。

自定义Segue示例

这个解决scheme将帮助你得到你的iOS 7应用程序的全面支持,他们将使用pushViewController方法推动你的视图和iOS 8,9等您的Segue将与新的(iOS 8)方法showViewController

不要忘记在你的故事板中的所有步骤都一样。

这仍然在iOS 10.x中发生

删除和重新设置赛门并没有为我解决任何问题:

问题:需要的function是7段,只能作为“推”(实际上是一个节目细节),但实际上只有我添加的第一个节点会推动,其他所有的行为都是模态的。 这是尽pipeInterface Builder描述每一个segues相同。

解决scheme:我不得不把这个动作加到6个没有的赛段上。

原始故事板XML

 <connections> <segue destination="tIr-4a-WfZ" kind="showDetail" identifier="A" action="showViewController:sender:" id="8yd-Ne-7KA"/> <segue destination="4mB-YE-5dM" kind="showDetail" identifier="B" id="Uod-JC-786"/> <segue destination="Qh5-bJ-KcE" kind="showDetail" identifier="C" id="3PW-nV-hWl"/> <segue destination="EI6-f4-QBB" kind="showDetail" identifier="D" id="WUK-ju-KDm"/> <segue destination="nTz-N4-fpW" kind="showDetail" identifier="E" id="Id6-bW-Huc"/> <segue destination="JEp-CH-6dW" kind="showDetail" identifier="F" id="G0L-XW-7f4"/> <segue destination="AET-S1-O6h" kind="showDetail" identifier="G" id="3NK-93-wTy"/> </connections> 

我通过添加showViewController:sender来改变这个

 <connections> <segue destination="tIr-4a-WfZ" kind="showDetail" identifier="A" action="showViewController:sender:" id="8yd-Ne-7KA"/> <segue destination="4mB-YE-5dM" kind="showDetail" identifier="B" action="showViewController:sender:" id="Uod-JC-786"/> <segue destination="Qh5-bJ-KcE" kind="showDetail" identifier="C" action="showViewController:sender:" id="3PW-nV-hWl"/> <segue destination="EI6-f4-QBB" kind="showDetail" identifier="D" action="showViewController:sender:" id="WUK-ju-KDm"/> <segue destination="nTz-N4-fpW" kind="showDetail" identifier="E" action="showViewController:sender:" id="Id6-bW-Huc"/> <segue destination="JEp-CH-6dW" kind="showDetail" identifier="F" action="showViewController:sender:" id="G0L-XW-7f4"/> <segue destination="AET-S1-O6h" kind="showDetail" identifier="G" action="showViewController:sender:" id="3NK-93-wTy"/> </connections>