情节提要Xcode 6中的自适应segue。是否不赞成使用push?


121

Xcode 6接口构建器默认情况下具有新的复选框“使用尺寸类别”。它使视图具有适应性。 在此处输入图片说明

当我尝试在情节提要中的2个视图之间进行选择时,我有新的选择: 在此处输入图片说明

而是旧的:

在此处输入图片说明

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

在此处输入图片说明

但这并没有推动。Segue动画看起来像是从底部滑动(模态),导航栏消失了。

问题是:如何使“显示”工作像推送?有可能还是应该改用“推(不推荐使用)”?在哪里可以找到有关新型扣押的任何信息?我在iOS8开发人员库中发现的唯一东西是Storyboards帮助您设计用户界面,但是没有有关“ show” segue的信息。

更新

我试图创建一个新项目,而“显示”确实像“推”一样工作。我认为项目中的问题可能是因为我将导航控制器与这样的代码一起使用,但是我不知道如何解决它。

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问题。

Answers:


97

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

如何使“显示”像推一样起作用?有可能还是应该改用“推(专用)”?

这应该; 它为我做。我正在使用Xcode 6 beta 2,并且测试使用单视图模板(在IB中调用预制视图控制器'VC_A')。然后,我添加了另一个视图控制器('VC_B')。然后,我在VC_A上添加了一个按钮以显示VC_B,另一个按钮从VC_B显示回VC_A。当我在情节提要中添加导航控制器作为初始视图控制器并将VC_A设置为rootViewController时,“ push”和“ show”都具有相同的效果。如果我没有初始的导航控制器,而是使用“显示”,那么您会得到您所描述的内容,即VC_B从底部向上滑动。如果我尝试“推送”,则会崩溃,因为要进行推送,我必须具有导航控制器。

在哪里可以找到有关新型扣押的任何信息?

所以,我发现了一些信息,在“什么在Interface Builder的新变化”会议在这里。如果您查看这些幻灯片,将会看到一张幻灯片(41)提及更改。观看会议视频时,您可以跳至38:00分钟,他们开始谈论自适应轮流。他们确实解释说,例如“显示”自适应选择在决定如何进行新视图控制器的呈现时考虑了上下文。


谢谢您的回答。我试图创建一个新项目,“显示”的工作原理确实与导航控制器的推送类似。在我的项目中,本课appcoda.com/ios-programming-sidebar-navigation-menu的侧边栏和推送工作结构很复杂,但显示却没有。可能是我重复使用导航控制器的原因。我已经用重用代码更新了我的问题。
约翰·卡康

因此,我在查看更新时首先看到的是您正在使用期望的自定义​​segue:“ SWRevealViewControllerSegue”,是的,在您的情况下,使用“ show”或“ push”可能是没有意义的,因为它们是内置的segues,而您想运行自己的自定义代码。当我下载示例项目时,它甚至会在情节提要文件中的segues上显示对“ custom”的选择。
Spencer Hall

我不是这个意思。我说的是在“ MainViewController”旁边创建新的UIViewController(它具有导航控制器,而我的“ update”仅显示如何将其在那里),并尝试将新的View推入MainViewController。故事板截图,如果你在示例项目启用“使用大小班”,创建NewViewController和“秀”尝试MainViewController和NewViewController之间化妆赛格瑞我会很感激。您会看到我在说什么。
John Kakon 2014年

刚才是否这样做,至少对我来说,“显示”的操作方式与“推”式相同。
斯宾塞·霍尔

9
您可以通过确保进入视图控制器的所有方式的根都具有UINavigationController来解决该错误。即使这意味着将UINavigationController放置到您的情节提要中,也将永远无法访问它。看起来接线是用来推断行为的。
Scott Robertson 2014年

33

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

如前所述,“推”和“模态”选项已被弃用,并分别由“显示”和“模态呈现”代替。根据Apple的文档,新的标记被进一步分为适合大小级别的标记。较旧的版本仅应用于支持比iOS 8早的iOS版本。

以下链接中的文档对此进行了解释,并说明了所有可用的旧版本和新版本。

在情节提要中的场景之间添加Segue

如果将来URL发生更改,这是每个新标记的说明:

表演

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

查看详细

在详细信息区域中显示内容。如果应用显示的是主视图和详细视图,则新内容将替换当前的详细信息。如果应用仅显示母版或详细信息,则内容将替换当前视图控制器堆栈的顶部。

模态呈现

模态呈现内容。有选择显示样式(UIModalPresentationStyle)和过渡样式(UIModalTransitionStyle)的选项。

呈现为Popover

将内容显示为锚定到现有视图的弹出式窗口。有一个选项可以指定在弹出视图(UIPopoverArrowDirection)的一个边缘上显示的箭头的可能方向。还有一个选项可以指定锚视图。


24

tldr; 从UIView / UIControl拖动到目标视图控制器,删除没有正确推送的Segue,然后在情节提要中重新创建它。

其他答案没有任何问题,但此答案可以说明正在发生的事情,如何验证正在发生的事情以及将来如何缓解此问题。

背景

就我而言,即使我已经有一个UINavigationController作为我的初始视图控制器(以我的内容UIViewController为根),我的Show Segues都没有工作。

表演节目中断的原因和方式

当显示情节在情节提要的源xml中具有与该情节相关联的动作时,它将中断。导致这种情况的典型情况是,您是否从先前在代码中调用的手动Segue中重新定义了Segue。这将在故事板xml中保留以下位。

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

Nota Bene 以xml形式查看情节提要;右键单击情节提要文件,然后选择“打开方式”>“源代码”。要还原,请使用打开方式>界面生成器-故事板

为了在使用情节提要中的segue时适应任何自定义动作,只需轻按prepareForSegue并拦截目标视图控制器,然后从该位置调用任何方法。在任何情况下,此小错误的副作用(该错误是以下事实:当您重新定义segue时,它没有在xml中正确设置〜即,即使您将segue更改为从UIView运行的segue之后,动作仍然存在。 UIControl)到目标视图控制器)。

不幸的是,最直接的解决方案失败了。因此,仅从情节提要中删除操作的xml属性不会解决问题。取而代之的是,只需删除并重新创建序列在情节中。

重新创建时,情节提要板xml将不再具有与特定segue相关的动作,并且Show将作为Push执行。

示例Xml以正确显示节目

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

减轻

为了防止重复发生,如果可能的话,只需使用prepareForSegue根据目标视图控制器添加所需的操作,就可以坚持非手动情节提要。或者,如果您必须混合搭配,请采取预防措施,以验证您的Show segues在故事图板xml中没有附加任何操作。如果您正在处理较旧的项目,则应特别注意Storyboard源代码,因为我发现了一些问题。


3
下班后,这可能节省了我几个小时。这是根据以上内容我将建议的内容:以源代码形式打开情节提要,搜索kind =“ show”,然后查看该行是否包含诸如action =“ showDetailViewController:sender:”之类的内容,如果是,则从action中删除所有内容=直到结束。我有一个非常大的情节提要,受影响的序列不包含此动作参数,但另一个不相关的行包含了。一旦删除动作,所有自适应序列都可以按预期的方式再次工作。只是删除受影响的序列就没有了。没事
马库斯

这也救了我。
亚当·巴登

1
删除XML中的action属性对我的朋友有用。
布伦特皇家-戈登

也救了我
吉米·乔治·托马斯

删除了xml文件中的action属性,瞧,它起作用了。没有这篇文章,永远不会发现问题。
krizzzn

20

正如斯科特·罗伯森(Scott Robertson)在这里评论的那样,这看起来像是iOS 7中的错误。

似乎在iOS 8中,过渡是在运行时推断出来的(正确的行为),而在iOS 7中,是在设计时推断出过渡的(错误的行为)。

最简单的解决方法是将一个未使用的导航控制器添加到情节提要中,并将其链接起来,以使所涉及的视图控制器成为此导航控制器的一部分。实际上,您不必实例化导航控制器,只需要越野车视图控制器即可知道它已嵌入在导航控制器中。

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

重现该错误:

  1. 创建一个使用大小类的新情节提要。
  2. 创建两个视图控制器(无导航控制器)。
  3. 例如,使第一视图控制器通过链接到按钮的“ 显示”(例如“推”)序列显示第二视图控制器。
  4. 在代码中,显示第一个视图控制器,但通过将其嵌入到导航控制器中 initWithRootViewController:方法。
  5. 在iOS 7上运行该应用程序。
  6. 点击应执行推送的按钮。
  7. 在iOS 7上,您将获得模式转换而不是推送。在iOS 8上,您将获得正确的推送行为。

在此处输入图片说明

要修复该错误:

  1. 将一个导航控制器添加到情节提要,并将第一个视图控制器设置为根视图控制器。(注意:添加第二个作为根视图控制器将无法修复此错误。)
  2. 给它一个垃圾标识符,以抑制有关导航控制器不可访问的警告,并向您自己证明它仅作为解决方法而存在。(例如workaround for show segues in iOS 7)。

在此处输入图片说明

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


1
谢谢,当我交换根NavigationControllers ViewController-Stack时,使用NavigationController的技巧为我完成了任务
Peter Pint 2015年

1
最佳解决方案。谢谢
ИльяГолованов

13

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

在这里写了一篇有关此的文章。

它易于复制;只要您在调用Showsegue 之前不以编程方式将视图控制器推入堆栈,iOS8上的iOS就可以很好地工作,甚至在iOS7.x中也可以。

如果仅使用情节提要板连接将其推入堆栈,它将起作用。但显然如果您通过某种方式通过代码推送navigationController,则推送属性UIViewController将是它属性,nil并且在调用Show时将假定其为模式,因为没有导航可控制堆栈。

到目前为止,仅解决方法是不通过代码推送(不可行)或使用现已弃用的Push

我提起了雷达(文章链接)。随时提交副本,希望苹果公司修复此问题。


3
这正是我的问题,谢谢!在这种情况下,使用已弃用的推送似乎是次要的解决方案。
Moshe Gottlieb 2014年

另一个解决方法是将一个(未使用的)导航控制器添加到情节提要中。见stackoverflow.com/questions/24184003/...
Senseful

不!它发生在这里,其原因不是以编程方式推动。在我的情况下,我执行Showsegue,然后在第二次Showsegue 上以模态显示,解决方案?
Frade 2015年

@Frade您可以链接到可重现的github存储库吗?您在哪个版本的iOS上运行?
esttorhe

私人项目。它发生试图执行(第二)时,Show在iOS 7的viewController的
Frade

2

我在Xcode 7和iOS 7.1.2中遇到了与segues相同的问题。Show segues(iOS 8的新功能)的工作原理如下 iOS 7中的模式Segues并且当您在Storyboard中使用Xcode定义segue类型时,不允许您将View Controller推入Navigation Controller堆栈。这就是为什么self.navigationController返回nil的原因,因为View Controller没有被推送到堆栈,并且您无法弹出它。

我不明白为什么当您需要您的应用程序在iOS 7上运行时,Apple在Xcode中没有为此案例添加任何通知。 他们说已弃用Push方法,但Show无法在iOS 7上正常工作。

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

我用.h创建了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

比您需要设置自定义情节提要中的每个segue类型并为其选择一个新的类,在我的例子中是MYShowSegue。

自定义Segue示例

此解决方案将帮助您获得对iOS 7应用程序的全面支持,它们将使用pushViewController方法推送视图,而对于iOS 8,9等。您的segue将与新(iOS 8)方法showViewController一起使用

不要忘记对情节提要中的所有脚本执行相同的操作。


不错的解决方案-为我工作(而不是添加“未使用的”导航控制器...
LaurenzGlück16年

1

这仍在iOS 10.x中发生

删除并重新启动segue对我没有任何帮助:

问题:必需的功能是7个segue,它们只能作为“推”操作(实际上是show Detail),但实际上只有我添加的第一个segue会推送,其他的都将以模态运行。尽管Interface Builder相同地描述了每个序列。

解决方案:我不得不将动作添加到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>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.