Adaptive segue in storyboard Xcode 6. Is push deprecated?
Xcode6接口生成器在默认情况下有新的复选框"使用大小类"。它使视图自适应。
当我试图在故事板中的两个视图之间切换时,我有了新的选择:
相反,旧:
现在我们有了"展示"和"呈现模式",而不是"推"和"模式"。旧选项标记为已弃用。我选择了"显示"选项,因为在Segue设置中它被称为"显示(例如推送)
但这并不能推动。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之后。
更新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视图控制器就可以知道它嵌入在导航控制器中。
注意:对于这些目的来说,模拟导航栏是不够的;您必须在其推送堆栈中有一个导航控制器。
要复制错误:
修复错误:
请注意导航控制器是如何添加到第二张图片中的,以及它没有任何输入箭头(即,除了使用视图控制器标识符之外,没有其他方法来实例化它)。
我知道我迟到了,但我想分享我学到的东西。这实际上是一个bug,目前仍然存在(2014-12-18)。
我在这里写了一篇关于这个的文章。
它很容易复制;在ios8上工作很好,甚至在ios7.x中,只要在调用
如果您只使用故事板连接推送到堆栈,它将工作;但显然,如果您通过代码推送,那么推送的
到目前为止,唯一的解决方法不是通过代码推送(不可行),也不是使用现在已被弃用的
我提交了一份雷达(文章的链接)。请随时提交副本,希望苹果能解决这个问题。
我在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> |