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

Adaptive segue in storyboard Xcode 6. Is push deprecated?

Xcode6接口生成器在默认情况下有新的复选框"使用大小类"。它使视图自适应。enter image description here

当我试图在故事板中的两个视图之间切换时,我有了新的选择:enter image description here

相反,旧:

enter image description here

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

enter image description here

但这并不能推动。Segue动画看起来像是从底部滑动(模式),导航栏消失。

问题是:我怎样才能让"表演"像推一样工作?有可能还是应该使用"push(已弃用)"代替?我在哪里可以找到关于新类型的segue的任何信息?我在IOS8开发人员库中发现的唯一一件事是,故事板可以帮助您设计用户界面,但是没有关于"show"segue的信息。

更新

我试着创建新的项目,"秀"实际上就像"推"。我认为我的项目中的问题可能是因为我用这样的代码重用导航控制器,但是我不知道如何修复它。

1
2
3
4
5
6
7
8
9
10
11
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];
    };

}

之后,我尝试将newviewcontroller推到mainviewcontroller之后。enter image description here

更新2:

我似乎只是iOS 7,iOS 7.1版。


是的,使用"表演"而不是"推"。

How can I make"show" work like push? Is it possible or should I use
"push (depricated)" instead?

它应该;它是为我做的。我正在使用Xcode6测试版2,为了测试我使用了单视图模板(调用ib'vc_a'中的预制视图控制器)。然后我添加了另一个视图控制器("vc_b")。然后我在vc_a上添加了一个按钮来显示vc_b,另一个从vc_b返回vc_a。当我在故事板中添加导航控制器作为初始视图控制器并使vc_a成为rootviewcontroller时,"push"和"show"都具有相同的效果。如果我没有一个初始的导航控制器,我使用"显示",我会得到你在VC中描述的从底部向上滑动。如果我试图"推",我会崩溃,因为要做"推",我必须有导航控制器。因此,在提供导航控制器的情况下,"显示"似乎会进行一次推送,如果不存在导航控制器,则以模式转换样式进行呈现。

Where can I find any information about new types of segue?

因此,我在"Interface Builder的新功能"会话中找到了一些信息。如果你看幻灯片,你会看到一张幻灯片(41)提到了变化。当观看该会话视频时,您可以跳到第38:00分钟,在那里他们开始谈论自适应信号段。他们解释说,例如,"显示"自适应segue在决定如何显示新的视图控制器时考虑了上下文。


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

如前所述,"推送"和"模态"段已被弃用,并分别被"显示"和"当前模态"所取代。根据苹果公司的文件,新的细分市场被进一步划分为适合大小分类的细分市场。旧版本仅用于支持早于iOS 8的iOS版本。

下面链接中的文档解释了这一点以及所有可用段(新旧段)的描述。

在故事板中的场景之间添加分隔符

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

Show

Present the content in the detail or master area depending on the content of the screen. If the app is displaying a master and detail view, the content is pushed onto the detail area. If the app is only displaying the master or the detail, the content is pushed on top of the current view controller stack.

Show Detail

Present the content in the detail area. If the app is displaying a master and detail view, the new content replaces the current detail. If the app is only displaying the master or the detail, the content replaces the top of the current view controller stack.

Present Modally

Present the content modally. There are options to choose a presentation style (UIModalPresentationStyle) and a transition style (UIModalTransitionStyle).

Present as Popover

Present the content as a popover anchored to an existing view. There is an option to specify the possible directions of the arrow shown on one edge of the popover view (UIPopoverArrowDirection). There is also an option to specify the anchor view.


tldr; Delete the Segue that is not pushing correctly and recreate it in the storyboard by dragging from a UIView/UIControl to the target
view controller.

其他答案没有错,但这一个解释了正在发生的事情,如何验证正在发生的事情,以及如何在未来缓解问题。

背景

在我的例子中,虽然我已经有了一个uinavigationcontroller作为初始视图控制器(以我的内容uiviewcontroller作为根),但我的所有显示段都没有工作。

为什么和如何表演塞格休息

当在故事板源XML中有一个与segue相关联的操作时,show segue将中断。造成这种情况的一个典型情况可能是,如果您已经从以前在代码中调用的手动segue中重新定义了segue。这会在故事板XML中留下以下部分。

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

Nota Bene
To view storyboard as xml; Right click the storyboard file and choose
Open as > Source Code. To revert use Open as > Interface Builder - Storyboard

要在使用故事板中的segue时适应任何自定义操作,只需点击PrepareForSegue并截获目标视图控制器,然后从该位置调用任何方法。在任何情况下,这个小bug的副作用(bug是这样一个事实,即当您重新定义segue时,它没有在XML中正确设置,即即使您将segue更改为从uiview(或uicontrol)操作到目标视图控制器的segue后,操作仍然保持不变)。

不幸的是,最直接的解决方案失败了。因此,仅仅从故事板中删除操作的XML属性并不能解决问题。相反,你必须简单地删除并重新创建故事板中的塞格。

重新创建后,故事板XML将不再具有与特定segue关联的操作,并且将以推送方式执行该节目。

用于正确显示segue的示例XML

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

缓解

为了防止再次发生,只要可能,您只需要使用PrepareForSegue添加基于目标视图控制器的所需操作,就可以坚持使用非手动故事板分段。或者,如果您必须混合和匹配,请采取预防措施来验证您的显示片段在故事板XML中没有附加任何操作。如果您处理的是较旧的项目,那么您应该特别注意故事板源代码,因为我发现了一些问题。


正如ScottRobertson在这里评论的,这看起来像iOS7中的一个bug。

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

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

注意:对于这些目的来说,模拟导航栏是不够的;您必须在其推送堆栈中有一个导航控制器。

要复制错误:

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

    修复错误:

  • 将导航控制器添加到情节提要,并将第一个视图控制器设置为根视图控制器。(注意:添加第二个作为根视图控制器不会修复此错误。)
  • 给它一个垃圾标识符来抑制关于导航控制器不可访问的警告,并向您自己记录它只是作为一个解决方案存在。(如workaround for show segues in iOS 7)。
  • enter image description here

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


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

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

    它很容易复制;在ios8上工作很好,甚至在ios7.x中,只要在调用Showsegue之前不将视图控制器以编程方式推入堆栈。

    如果您只使用故事板连接推送到堆栈,它将工作;但显然,如果您通过代码推送,那么推送的UIViewControllernavigationController属性将是nil,并且当您调用Show时,它将假定它是一种模式,因为没有导航来控制堆栈。

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

    我提交了一份雷达(文章的链接)。请随时提交副本,希望苹果能解决这个问题。


    我在xcode 7和ios7.1.2中也遇到了同样的问题。show segues(iOS 8的新功能)的工作方式与iOS 7中的模式segues类似,并且在故事板中使用xcode定义segue类型时,不允许将视图控制器推到导航控制器堆栈中。这就是为什么self.navigationcontroller将返回nil的原因,因为视图控制器没有被推到堆栈中,并且您无法将其弹出。

    我不明白为什么苹果没有在Xcode中为这个案例添加任何通知,当你需要你的应用在iOS7上工作时。他们说push方法已经被弃用,但是show在iOS7中不能正常工作。

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

    我用.h创建了自己的howsegue类。

    1
    2
    3
    4
    5
    #import <UIKit/UIKit.h>

    @interface MYShowSegue : UIStoryboardSegue

    @end

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    #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。

    别忘了对故事板上的所有片段都这么做。


    这仍然发生在iOS 10.x中

    删除和重新安装Segues并不能为我解决任何问题:

    问题:所需的功能是7段,只作为一个"推"(实际上是一个显示细节)操作,但事实上,只有我添加的第一段会推,其他的都会表现出模态。尽管接口生成器对每个段进行了相同的描述。

    解决方案:我必须将这个动作添加到没有它的6个分段中。

    原始情节提要XML

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <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更改了此设置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <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>