热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

故事板Xcode6中的自适应segue。将弃用吗?-AdaptivesegueinstoryboardXcode6.Ispushdeprecated?

Xcode6interfacebuilderbydefaulthasnewcheckboxusesizeclasses.Itmakesviewsadaptive.

Xcode 6 interface builder by default has new checkbox "use size classes". It makes views adaptive. enter image description here

Xcode 6接口构建器默认有新的复选框“使用大小类”。它使自适应的看法。

When I try to make segue between 2 views in my storyboard I have new options: enter image description here

当我试图在我的故事板中的两个视图之间进行segue时,我有了新的选项:

instead old:

而不是老:

enter image description here

Now we have "show" and "present modally" instead of "push" and "modal". The old options are marked as deprecated. I've chosen "show" option, because in segue settings it called "show (e.g. push)

现在我们有“show”和“present modally”而不是“push”和“modal”。旧的选项被标记为弃用。我选择了“show”选项,因为在segue的设置中它被称为“show(例如push)”

enter image description here

But it doesn't make push. Segue animation looks like slide from the bottom (modal) and navigation bar disappears.

但它不会推。Segue动画从底部(模式)和导航栏消失。

Question is: How can I make "show" work like push? Is it possible or should I use "push (deprecated)" instead? Where can I find any information about new types of segue? The only thing that I've found in iOS8 developer library is Storyboards Help You Design Your User Interface but there is no information about "show" segue.

问题是:我怎样才能让“显示”工作像push?是可能的还是应该使用“push(弃用)”呢?在哪里可以找到关于新类型segue的信息?我在iOS8 developer library中发现的唯一一件事是storyboard帮助您设计用户界面,但是没有关于“show”segue的信息。

UPDATE

I tried to create new project and "show" is really works like "push". I think the issue in my project can be because I reuse navigation controller with code like this, but I don't know how to fix it.

我试着创建一个新的项目,“show”真的很像“push”。我认为我的项目中的问题可能是因为我重用了像这样代码的导航控制器,但我不知道如何修复它。

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];
    };

}

After that I try to push NewViewController after MainViewController enter image description here

之后,我尝试在MainViewController之后推出NewViewController。

UPDATE 2:

I seems to be only iOS 7, iOS 7.1 issue.

我似乎只是ios7, iOS 7.1的问题。

7 个解决方案

#1


91  

Yes, use ‘Show’ instead of ‘Push’

是的,用“Show”而不是“Push”

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

我怎样才能让“显示”工作像push?是可能的还是应该用“push(被剥夺的)”代替?

It should; it does for me. I am using Xcode 6 beta 2 and to test I used the single view template (calling the pre made view controller in IB ‘VC_A’). I then added another view controller (‘VC_B’). I then added a button on VC_A to show VC_B and another from VC_B back to VC_A. When I add a navigation controller as the initial view controller in the storyboard and make VC_A the rootViewController, both ‘push’ and ‘show’ have the same effect. If I don’t have an initial navigation controller and I use ‘show’ I get what you described in that the VC_B does a slide up from bottom. If I try to ‘push’ I get a crash since in order to do push I must have navigation controller. So it would seem that ‘show’ will do a push in the case where a navigation controller is provided and do a present with a modal transition style if a navigation controller is not present.

它应该;它对我来说。我使用Xcode 6 beta 2和测试我使用了单一视图模板(在IB ' VC_A '中调用pre - made视图控制器)。然后我添加了另一个视图控制器(' VC_B ')。然后我在VC_A上添加了一个按钮来显示VC_B和另一个从VC_B返回到VC_A的按钮。当我在故事板中添加一个导航控制器作为初始视图控制器并使VC_A为rootViewController时,“push”和“show”都有相同的效果。如果我没有初始导航控制器,我用' show '我得到你所描述的VC_B从底部向上滑动。如果我尝试“推”,我就会崩溃,因为要做push,我必须有导航控制器。因此,如果导航控制器不存在,“show”将会在导航控制器提供的情况下进行推送,并使用模式转换样式进行演示。

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

在哪里可以找到关于新类型segue的信息?

So I found some information in the ‘What’s New in Interface Builder’ session here. If you look at the slides you will see one slide (41) mention the change. When watching that session video you can skip to minute 38:00 where they start talking about adaptive segues. They do explain that the ‘show’ adaptive segue, for example, takes the context in account when deciding how to do the presentation of a new view controller.

所以我在这里找到了一些信息。如果你看幻灯片,你会看到一张幻灯片(41)提到了变化。当观看这段视频时,你可以跳到38:00,在那里他们开始谈论自适应segue。例如,他们确实解释了“show”adaptive segue在决定如何做一个新的视图控制器时,考虑了上下文。

#2


32  

There is already an accepted answer, but I wanted to give a bit more information, possibly information that was not available before.

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

As was mentioned previously, the "push" and "modal" segues were deprecated, and have been replaced by "show" and "present modally" respectively. According to Apple's documentation, the new segues have been further divided into segues that adapt to size classes. The older ones should only be used to support iOS versions older than iOS 8.

如前所述,“push”和“modal”segue被弃用,分别被“show”和“present modally”取代。根据苹果公司的文档,新的segue被进一步划分为适应大小类的segue。旧的版本应该只支持iOS 8版本的iOS版本。

The document in the following link explains that and the description of all the available segues, old and new.

下面链接中的文档解释了所有可用segue的描述,旧的和新的。

Adding a Segue Between Scenes in a Storyboard

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

In case the URL changes in the future, this is the explanation given for each new segue:

如果将来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.

根据屏幕内容显示细节或主区域的内容。如果应用程序显示一个主视图和细节视图,则将内容推送到细节区域。如果该应用程序只是显示master或detail,则将内容推送到当前视图控制器堆栈的顶部。

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.

在细节区域显示内容。如果应用程序显示一个主视图和细节视图,那么新的内容将取代当前的细节。如果应用程序只是显示master或detail,则内容将替换当前视图控制器堆栈的顶部。

Present Modally

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

模式的内容。有一些选项可以选择表示样式(UIModalPresentationStyle)和转换样式(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.

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

#3


23  

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.

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

There is nothing wrong with the other answers but this one explains what is happening, how you can verify that it is happening and how to mitigate the issue in the future.

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

Background

背景

In my case, none of my Show Segues were working even though I already had a UINavigationController as my initial view controller (with my content UIViewController as it's root).

在我的例子中,虽然我已经有一个UINavigationController作为我的初始视图控制器(我的内容UIViewController是root),但是我的Show Segues没有一个是工作的。

Why and How the Show Segue Breaks

为什么和如何显示Show Segue中断?

The Show segue breaks when it has an action associated with the segue within the storyboard's source xml. A typical scenario causing this might be if you have redefined a segue from a manual segue previously called in code. This leaves the following bits in the storyboard xml.

当在故事板的源xml中有一个与segue关联的动作时,Show segue中断。一个典型的场景可能是,如果您从以前调用的手动segue重新定义了一个segue。这将在故事板xml中留下以下部分。


    

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

Nota Bene将故事板视为xml;右键单击故事板文件,选择Open作为>源代码。恢复使用Open作为>界面构建器-故事板。

To accommodate any custom actions when using the segue from the storyboard one can just tap into prepareForSegue and intercept the destination view controller and call any methods from that location. In any case, the side effect for this little bug (the bug is the fact that when you redefine the segue it is not properly setup in xml ~ i.e. the action remains even after your change the segue to one that operates from a UIView (or UIControl) to a target view controller).

为了适应任何自定义操作,当使用从故事板中使用segue时,你只需点击prepareForSegue并截获目标视图控制器,并从该位置调用任何方法。在任何情况下,它的副作用小错误(bug是这样一个事实,当你用xml定义segue不正确设置~即行动仍然是即使你改变segue从UIView一个操作(或UIControl)目标视图控制器)。

Unfortunately the most direct solution fails. So just removing the xml attribute for the action from within the Storyboard will NOT fix the problem. Instead one has to simply delete and recreate the segue in the storyboard.

不幸的是,最直接的解决方案失败了。因此,从故事板中删除操作的xml属性将不会解决问题。相反,我们必须在故事板中简单地删除和重新创建segue。

When recreated the storyboard xml will no longer have an action associated with the particular segue and the Show will execute as a Push.

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

Sample Xml for correct Show Segue

用于正确显示Segue的示例Xml。

  
    
  

Mitigation

缓解

To prevent recurrence one just needs to stick to non-manual storyboard segues if possible by using the prepareForSegue to add required actions based on destination view controller. Or if you must to mix and match, take the precaution to verify that your Show segues do not have any actions attached in the storyboard xml. If you are dealing with older projects then you should give special attention to the Storyboard source code as I've discovered a few issues.

为了防止递归,只要使用prepareForSegue来添加基于目标视图控制器的所需操作,就需要使用非手工故事板segue。或者,如果您必须混合和匹配,则采取预防措施来验证您的Show segues没有在故事板xml中附加任何操作。如果您正在处理较老的项目,那么您应该特别注意故事板源代码,因为我已经发现了一些问题。

#4


20  

As Scott Robertson commented here, this looks like a bug in iOS 7.

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

It appears that in iOS 8 the transition is inferred at runtime (correct behavior), while in iOS 7 the transition is inferred at design time (buggy behavior).

在ios8中,在运行时(正确的行为),转换是推断出来的,而在ios7中,转换是在设计时推断的(错误行为)。

The simplest workaround is to add an unused navigation controller to the storyboard and link it up so that the view controller in question is part of this navigation controller. You don't actually have to instantiate the navigation controller, you just need the buggy view controller to know it is embedded in a navigation controller.

最简单的解决方法是将一个未使用的导航控制器添加到故事板中,并将其链接起来,从而使问题中的视图控制器成为导航控制器的一部分。你实际上不需要实例化导航控制器,你只需要一个小车视图控制器知道它嵌在导航控制器中。

Note: Simulating a navigation bar is not sufficient for these purposes; you must actually have a navigation controller in its push stack.

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

To reproduce the bug:

复制错误:

  1. Create a new storyboard that uses size classes.
  2. 创建一个使用大小类的新故事板。
  3. Create a two view controllers (no navigation controllers).
  4. 创建两个视图控制器(没有导航控制器)。
  5. Make the first view controller show the second view controller via a Show (e.g. Push) segue linked to a button, for example.
  6. 例如,让第一个视图控制器通过一个与按钮相连的show(例如Push) segue显示第二个视图控制器。
  7. In code, show the first view controller, but embed it in a navigation controller via the initWithRootViewController: method.
  8. 在代码中,显示第一个视图控制器,但通过initWithRootViewController:方法将其嵌入到导航控制器中。
  9. Run the app on iOS 7.
  10. 在ios7上运行这个应用程序。
  11. Tap the button that should perform the push.
  12. 点击应该执行推送的按钮。
  13. You will get a modal transition instead of a push on iOS 7. On iOS 8 you will get the correct, push behavior.
  14. 你将会得到一个模态转换而不是在ios7上的push。在ios8上,你会得到正确的推送行为。

enter image description here

To fix the bug:

修复bug:

  1. Add a navigation controller to the storyboard and set the first view controller to be the root view controller. (Note: adding the second as the root view controller will NOT fix this bug.)
  2. 在故事板中添加一个导航控制器,并将第一个视图控制器设置为根视图控制器。(注意:添加第二个作为根视图控制器将不会修复这个错误。)
  3. Give it a junk identifier to suppress the warning about the navigation controller being inaccessible, and to document to yourself that it exists solely as a workaround. (e.g. workaround for show segues in iOS 7).
  4. 给它一个垃圾标识符来抑制关于导航控制器不可访问的警告,并将它单独作为一个工作区来记录。(例如,在ios7中显示segue)。

enter image description here

Notice how the navigation controller was added in the second picture, and how it doesn't have any incoming arrows (i.e. there is no way to instantiate it other than using its view controller identifier).

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

#5


13  

I know I'm late to this but I wanted to share what I learned. This is in fact a bug and is still present today (2014-12-18).

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

I wrote an article about this here.

我在这里写了一篇文章。

It is easily reproducible; on iOS8 will work just fine and even in iOS7.x as long as you don't push a view controller programmatically into the stack before calling the Show segue.

它很容易重现;在iOS8上,即使在iOS7中也可以工作。只要在调用Show segue之前,不要以编程方式将视图控制器推入堆栈。

If you only push to the stack using storyboard connections it will work; but apparently if you push via code somehow the navigationController property of the pushed UIViewController will be nil and when you call Show it will assume its a modal because there's no navigation to control the stack.

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

Only workaround so far is either not push via code (not feasible) or use the now deprecated Push.

到目前为止,只有解决方案不是通过代码(不可行),或者使用现在弃用的push。

I filed a radar (link on the article). Feel free to file duplicates with the hopes of Apple fixing this issue.

我提交了一个雷达(链接在文章上)。您可以随意复制,希望苹果解决这个问题。

#6


2  

I had the same issue with segues in Xcode 7 and iOS 7.1.2. Show segues (new feature from iOS 8) works like modal segues in iOS 7 and do not allow you to push your View Controllers into the Navigation Controller stack when you define segue type with Xcode in your Storyboard. That's why your self.navigationController will return nil, because the View Controller was not pushed to the stack and you can not pop it.

在Xcode 7和ios7.1.2中,我也遇到了同样的问题。显示segue (iOS 8的新特性)就像ios7中的模态segue一样,当你在故事板中定义segue类型时,不允许你将视图控制器推送到导航控制器堆栈中。这就是为什么你自己。navigationController将返回nil,因为视图控制器没有被推送到堆栈中,所以不能弹出它。

I don't understand why Apple did not add any notifications for this case in Xcode when you need your app to work on iOS 7. They say that Push method is Deprecated, but Show does not work correctly with iOS 7.

我不明白为什么苹果没有在Xcode中为这个案例添加任何通知,因为你需要你的应用在ios7上工作。他们说Push方法是不赞成的,但是在ios7中显示不能正常工作。

What have i did to resolve the issue:

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

I have created MYShowSegue class with .h

我使用.h创建了MYShowSegue类。

#import 

@interface MYShowSegue : UIStoryboardSegue

@end

And .m file with only one perform method:

和。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

Than you need to set a Custom type for each segue in your Storyboard and select a new class for it, in my case it was MYShowSegue.

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

Custom Segue Example

自定义Segue例子

This solution will help you to get a full support of your iOS 7 apps, they will use pushViewController method to push your Views and for iOS 8,9 etc. your segue will work with new (iOS 8) method showViewController

这个解决方案将帮助您得到您的iOS 7应用程序的完全支持,他们将使用pushViewController方法来推送您的视图,对于iOS 8、9等,您的segue将使用新的(ios8)方法showViewController。

Do not forget to do the same with all your segues in your Storyboard.

不要忘记在故事板中使用所有的segue。

#7


1  

This is still happening in iOS 10.x

这仍然在iOS 10.x中发生。

Deleting and re-instating segues did not solve anything for me:

删除和恢复segue并没有为我解决任何问题:

Problem: Requred functionality was 7 segues which only operate as a 'push' (actually a show Detail) but in fact only the first segue I added would push, the others would all behave modally. This is despite Interface Builder describing each of the segues identically.

问题:Requred功能是7个segue,它只作为一个“push”(实际上是一个显示细节),但实际上,我添加的第一个segue会推动,其他的都将会以模态方式运行。尽管接口生成器对每个segue都进行了相同的描述。

Solution: I had to add the action to the 6 segues which didn't have it.

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

Original Storyboard XML

原始故事板XML


  
  
  
  
  
  
  

I changed this by adding showViewController:sender

我通过添加showViewController:sender来改变这一点。


  
  
  
  
  
  
  


推荐阅读
  • 深入解析 Android IPC 中的 Messenger 机制
    本文详细介绍了 Android 中基于消息传递的进程间通信(IPC)机制——Messenger。通过实例和源码分析,帮助开发者更好地理解和使用这一高效的通信工具。 ... [详细]
  • 深入解析SpringMVC核心组件:DispatcherServlet的工作原理
    本文详细探讨了SpringMVC的核心组件——DispatcherServlet的运作机制,旨在帮助有一定Java和Spring基础的开发人员理解HTTP请求是如何被映射到Controller并执行的。文章将解答以下问题:1. HTTP请求如何映射到Controller;2. Controller是如何被执行的。 ... [详细]
  • 本文介绍了如何在iOS应用中自定义导航栏按钮,包括使用普通按钮和图片生成导航条专用按钮的方法。同时,探讨了在不同版本的iOS系统中实现多按钮布局的技术方案。 ... [详细]
  • 本文介绍如何使用 Android 的 Canvas 和 View 组件创建一个简单的绘图板应用程序,支持触摸绘画和保存图片功能。 ... [详细]
  • 采用IKE方式建立IPsec安全隧道
    一、【组网和实验环境】按如上的接口ip先作配置,再作ipsec的相关配置,配置文本见文章最后本文实验采用的交换机是H3C模拟器,下载地址如 ... [详细]
  • 深入解析Java枚举及其高级特性
    本文详细介绍了Java枚举的概念、语法、使用规则和应用场景,并探讨了其在实际编程中的高级应用。所有相关内容已收录于GitHub仓库[JavaLearningmanual](https://github.com/Ziphtracks/JavaLearningmanual),欢迎Star并持续关注。 ... [详细]
  • Redux入门指南
    本文介绍Redux的基本概念和工作原理,帮助初学者理解如何使用Redux管理应用程序的状态。Redux是一个用于JavaScript应用的状态管理库,特别适用于React项目。 ... [详细]
  • 在高并发需求的C++项目中,我们最初选择了JsonCpp进行JSON解析和序列化。然而,在处理大数据量时,JsonCpp频繁抛出异常,尤其是在多线程环境下问题更为突出。通过分析发现,旧版本的JsonCpp存在多线程安全性和性能瓶颈。经过评估,我们最终选择了RapidJSON作为替代方案,并实现了显著的性能提升。 ... [详细]
  • 深入解析Spring启动过程
    本文详细介绍了Spring框架的启动流程,帮助开发者理解其内部机制。通过具体示例和代码片段,解释了Bean定义、工厂类、读取器以及条件评估等关键概念,使读者能够更全面地掌握Spring的初始化过程。 ... [详细]
  • 本文介绍了如何在 C# 和 XNA 框架中实现一个自定义的 3x3 矩阵类(MMatrix33),旨在深入理解矩阵运算及其应用场景。该类参考了 AS3 Starling 和其他相关资源,以确保算法的准确性和高效性。 ... [详细]
  • 在尝试使用C# Windows Forms客户端通过SignalR连接到ASP.NET服务器时,遇到了内部服务器错误(500)。本文将详细探讨问题的原因及解决方案。 ... [详细]
  • 主调|大侠_重温C++ ... [详细]
  • 本文将详细探讨 Java 中提供的不可变集合(如 `Collections.unmodifiableXXX`)和同步集合(如 `Collections.synchronizedXXX`)的实现原理及使用方法,帮助开发者更好地理解和应用这些工具。 ... [详细]
  • 在寻找轻量级Ruby Web框架的过程中,您可能会遇到Sinatra和Ramaze。两者都以简洁、轻便著称,但它们之间存在一些关键区别。本文将探讨这些差异,并提供详细的分析,帮助您做出最佳选择。 ... [详细]
  • HDU 2871 内存管理问题(线段树优化)
    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2871。本题涉及内存管理操作,包括重置、申请、释放和查询内存块。通过使用线段树进行高效管理和维护。 ... [详细]
author-avatar
纸灰机forever
这个家伙很懒,什么也没留下!
Tags | 热门标签
RankList | 热门文章
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有