热门标签 | 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来改变这一点。


  
  
  
  
  
  
  


推荐阅读
  • 我收到这个错误.我怎么能在我的情况下解决这个问题?Bitmapcannotberesolvedtoatype发生错误的行publicvoidonPageStart ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • IhaveconfiguredanactionforaremotenotificationwhenitarrivestomyiOsapp.Iwanttwodiff ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • 李逍遥寻找仙药的迷阵之旅
    本文讲述了少年李逍遥为了救治婶婶的病情,前往仙灵岛寻找仙药的故事。他需要穿越一个由M×N个方格组成的迷阵,有些方格内有怪物,有些方格是安全的。李逍遥需要避开有怪物的方格,并经过最少的方格,找到仙药。在寻找的过程中,他还会遇到神秘人物。本文提供了一个迷阵样例及李逍遥找到仙药的路线。 ... [详细]
  • 本文介绍了Codeforces Round #321 (Div. 2)比赛中的问题Kefa and Dishes,通过状压和spfa算法解决了这个问题。给定一个有向图,求在不超过m步的情况下,能获得的最大权值和。点不能重复走。文章详细介绍了问题的题意、解题思路和代码实现。 ... [详细]
  • STL迭代器的种类及其功能介绍
    本文介绍了标准模板库(STL)定义的五种迭代器的种类和功能。通过图表展示了这几种迭代器之间的关系,并详细描述了各个迭代器的功能和使用方法。其中,输入迭代器用于从容器中读取元素,输出迭代器用于向容器中写入元素,正向迭代器是输入迭代器和输出迭代器的组合。本文的目的是帮助读者更好地理解STL迭代器的使用方法和特点。 ... [详细]
  • 本文介绍了一道经典的状态压缩题目——关灯问题2,并提供了解决该问题的算法思路。通过使用二进制表示灯的状态,并枚举所有可能的状态,可以求解出最少按按钮的次数,从而将所有灯关掉。本文还对状压和位运算进行了解释,并指出了该方法的适用性和局限性。 ... [详细]
  • linux进阶50——无锁CAS
    1.概念比较并交换(compareandswap,CAS),是原⼦操作的⼀种,可⽤于在多线程编程中实现不被打断的数据交换操作࿰ ... [详细]
  • C++ STL复习(13)容器适配器
    STL提供了3种容器适配器,分别为stack栈适配器、queue队列适配器以及priority_queue优先权队列适配器。不同场景下,由于不同的序列式 ... [详细]
  • ihaveusedthedelphidatabindingwizardwithmyxmlfile,andeverythingcompilesandrunsfine. ... [详细]
  • Android NDK开发的一点尝试
    写在前面笔者是一个“原始”的C++开发者,对Java编程虽说不上抵触但也没有C++那么顺手。而且,作为一个游戏引擎,不管是在什么地方,效率总是第一位的,尤其是在移动平台这样资源吃紧 ... [详细]
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社区 版权所有