故事板中的自适应segue Xcode 6.推送是否被弃用?

时间:2014-06-12 12:08:58

标签: storyboard push ios8 xcode6

默认情况下,Xcode 6界面构建器具有新复选框"使用大小类"。它使视图自适应。 enter image description here

当我尝试在故事板中的2个视图之间制作segue时,我有了新的选择: enter image description here

相反旧:

enter image description here

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

enter image description here

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

问题是:如何制作" show"工作就像推?是否有可能或者我应该使用"推(弃用)"代替?我在哪里可以找到有关新型segue的任何信息?我在iOS8开发人员库中找到的唯一内容是Storyboards Help You Design Your User Interface,但没有关于" show"的信息。 SEGUE。

更新

我尝试创建新项目" show"真的像'#34;推"。 我认为我的项目中的问题可能是因为我重复使用导航控制器这样的代码,但我不知道如何修复它。

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 enter image description here

更新2:

我似乎只是iOS 7,iOS 7.1问题。

7 个答案:

答案 0 :(得分:94)

是的,请使用“显示”代替“推送”

  

我如何制作" show"工作就像推?是否可能或应该使用   "推(豁免)"代替?

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

  

我在哪里可以找到有关segue新类型的任何信息?

所以我在“界面生成器中的新功能”会话here中找到了一些信息。如果您查看幻灯片,您会看到一张幻灯片(41)提到了更改。观看该会话视频时,您可以跳到38:00,开始谈论自适应segues。例如,他们确实解释了“show”自适应segue在决定如何进行新视图控制器的呈现时会考虑上下文。

答案 1 :(得分:32)

已经有一个已接受的答案,但我想提供更多信息,可能是之前无法获得的信息。

如前所述,“推”和“模态”segue已被弃用,并分别被“show”和“present modally”取代。根据Apple的文档,新的segues进一步划分为适应大小等级的segue。较旧的版本仅应用于支持早于iOS 8的iOS版本。

以下链接中的文档说明了所有可用的segue,旧的和新的描述。

Adding a Segue Between Scenes in a Storyboard

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

  

显示

     

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

     

显示详细信息

     

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

     

以模态呈现

     

以模态方式呈现内容。可以选择演示样式(UIModalPresentationStyle)和过渡样式(UIModalTransitionStyle)。

     

以Popover身份出现

     

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

答案 2 :(得分:23)

  

tldr; 删除未正确推送的Segue,并通过从UIView / UIControl拖动到目标,在故事板中重新创建它   查看控制器。

其他答案没有错,但是这个解释了发生了什么,如何验证它是否正在发生以及如何在将来缓解这个问题。

<强>背景

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

Show Segue Break的原因和方式

当故事板的源xml中有与segue相关联的动作时,Show 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格式查看故事板;右键单击故事板文件并选择   打开为&gt;源代码。要恢复使用,请打开&gt;界面生成器 - 故事板

要在使用故事板中的segue时适应任何自定义操作,只需点击prepareForSegue并拦截目标视图控制器并从该位置调用任何方法。在任何情况下,这个小错误的副作用(错误是当你重新定义segue时它没有在xml中正确设置〜即,在你将segue改为从UIView操作的一个之后,动作仍然存在(或者UIControl)到目标视图控制器)。

不幸的是,最直接的解决方案失败了。因此,只需从故事板中删除操作的xml属性, NOT 即可解决问题。相反,必须简单地删除并重新创建故事板中的segue

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

示例Xml以获得正确的Show Segue

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

<强>缓解措施

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

答案 3 :(得分:20)

作为Scott Robertson commented here,这看起来像是iOS 7中的一个错误。

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

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

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

要重现错误:

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

    修复错误:

    1. 将导航控制器添加到情节提要板,并将第一个视图控制器设置为根视图控制器。 (注意:添加第二个作为根视图控制器将不会修复此错误。)
    2. 给它一个垃圾标识符以禁止关于导航控制器无法访问的警告,并向自己记录它仅作为变通方法存在。 (例如workaround for show segues in iOS 7)。
    3. enter image description here

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

答案 4 :(得分:13)

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

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

易于重现;只要你在调用Show segue之前不以编程方式将视图控制器推入堆栈,iOS8上的工作就可以正常工作,甚至可以在iOS7.x中工作。

如果您只使用故事板连接推送到堆栈,它将起作用;但显然如果你通过代码推送,推送navigationController的{​​{1}}属性将是UIViewController,当你调用nil时,它会假设它是一个模态因为那里有'{1}}。没有导航来控制堆栈。

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

我提交了雷达(文章链接)。随着Apple修复此问题的希望,请随意提交重复文件。

答案 5 :(得分:2)

我在Xcode 7和iOS 7.1.2中遇到了与segue相同的问题。 显示segues(来自iOS 8的新功能)的工作方式类似于iOS 7中的模态segue ,并且当您在Storyboard中使用Xcode定义segue类型时,不允许将视图控制器推入导航控制器堆栈。这就是你的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

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

Custom Segue Example

此解决方案将帮助您获得iOS 7应用程序的完全支持,他们将使用 pushViewController 方法推送您的视图和iOS 8,9等。您的segue将使用新的( iOS 8)方法 showViewController

不要忘记对故事板中的所有段落做同样的事情。

答案 6 :(得分:1)

这仍然发生在iOS 10.x

删除和重新安排segues并没有为我解决任何问题:

问题:需要的功能是7个segues,只能作为“推送”操作。 (实际上是一个节目细节)但实际上只有我添加的第一个segue会推,其他的都会表现出模态。尽管Interface Builder完全相同地描述了每个segue。

解决方案:我不得不将动作添加到没有它的6个segues中。

原始故事板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>