简体   繁体   English

故事板+大小类:如何为不同的设备/大小类实现不同的Segues,ViewControllers,UserFlow?

[英]Storyboards + Size Classes: How to implement different Segues, ViewControllers, UserFlow for different devices / size classes?

an existing iOS 7+ app supports iPhone and iPad. 现有的iOS 7+应用程序支持iPhone和iPad。 Currently I am using two different Storyboards for iPhone and iPad layout which works fine. 目前我使用两种不同的故事板进行iPhone和iPad布局,效果很好。 Now I am trying to convert this to a One-Storyboard-Layout using Adaptive Size Classes. 现在我尝试使用自适应大小类将其转换为One-Storyboard-Layout。

My problem is, that my iPhone and iPad layouts are quite different. 我的问题是,我的iPhone和iPad布局完全不同。 They not only use different sizes and positions for their controls but also some totally different View Controllers. 它们不仅为控件使用不同的大小和位置,还使用一些完全不同的视图控制器。

Both Storyboards use a MMDrawerController as initial VC. 两个故事板都使用MMDrawerController作为初始VC。 But from there on the control flow is different. 但是从那里开始,控制流程就不同了。 While the iPad Storyboard uses a UISplitViewController as base for all other ViewControllers the iPhone uses a UITabBarViewController instead. 虽然iPad Storyboard使用UISplitViewController作为所有其他ViewControllers的基础,但iPhone使用的是UITabBarViewController

This is just one difference but there are others. 这只是一个区别,但还有其他一些。 How should these differences be handled in one Storyboard? 如何在一个故事板中处理这些差异? To achive this, I would have to specific different segues depending on the current Size Class. 为了达到这个目的,我将根据当前的Size Class来定义不同的segue。 But as far as I know this is not possible. 但据我所知,这是不可能的。

Some of the new iOS 8 adaptive Segues can behave differently depending on the Size Class but as far as I know it is not possible to specify different segues for different Size Classes. 一些新的iOS 8自适应Segues的行为可能会有所不同,具体取决于Size Class,但据我所知,不可能为不同的Size Classes指定不同的segue。 Additionally it is not possible to define different initial ViewControllers depending on the Size Class. 此外,根据Size Class,无法定义不同的初始ViewControllers。

So the question is: Is it possible to specify two different layouts (including different Segues, ViewControllers, etc.) in one Storyboard? 所以问题是:是否可以在一个故事板中指定两种不同的布局(包括不同的Segues,ViewControllers等)?

The reason to switch to a single Storyboard is to support the new Split Screen and Slide Over features in iOS 9. Loading different Storyboards at startup depending on the the screen size / size class is easy. 切换到单个Storyboard的原因是支持iOS 9中的新分屏和幻灯片功能。在启动时加载不同的故事板取决于屏幕大小/大小类很容易。 But switching to another Storyboard at runtime when the size class is changed dynamically is not possible. 但是,当动态更改大小类时,无法在运行时切换到另一个Storyboard。 Is it? 是吗?

I have just gone through similar pain, and found that the only real way to handle the larger differences is to create separate controllers and segues in storyboard as normal, but to execute them in code rather than relying on segue activation created in storyboard. 我刚刚经历了类似的痛苦,并发现处理更大差异的唯一真正方法是在故事板中正常创建单独的控制器和segue,但是在代码中执行它们而不是依赖于在storyboard中创建的segue激活。

In my case I was using a side menu on both iPhone and iPad, but on iPad was using split view controllers for the main display versus UINavigationController on iPhone. 在我的情况下,我在iPhone和iPad上使用侧边菜单,但在iPad上使用分割视图控制器作为主显示器而不是iPhone上的UINavigationController。 An added complication is that on iOS8, UISplitViewController is supported on iPhone but not on iOS7 where it is treated as a UINavigationController. 另外一个复杂的问题是,在iOS8上,UISplitViewController在iPhone上受支持,但在iOS7上则不受支持,因为它被视为UINavigationController。

As far as I know, you cannot use size class to automatically trigger a segue of the right type. 据我所知,你不能使用size类自动触发正确类型的segue。 However you can do that in code as long as you have a mechanism for making the choice. 但是,只要您有一个进行选择的机制,您就可以在代码中执行此操作。 So you can still create segues for each size class, or better your mode of display for a given device type, and call the right one from code. 因此,您仍然可以为每个大小的类创建segue,或者更好地为给定的设备类型创建显示模式,并从代码中调用正确的。

Your biggest issue will be the iOS9 split screen which seems to dynamically change the size class from iPad regularW/regularH to iPad compactW/regularH and back as you swipe. 你最大的问题将是iOS9分屏,它似乎动态地将尺寸等级从iPad regularW / regularH改为iPad compactW / regularH,然后再滑动。 You will be ok for things like split views which will simply switch to look like a navigation controller stack. 您可以选择拆分视图,只需切换到导航控制器堆栈即可。 I can see no way though to switch to a tab bar say on the fly unless you pop back to the root, have the app delegate switch the root screen and navigate you back to the same place. 我可以看到没有办法切换到标签栏,除非你弹回根,让app委托切换根屏幕并导航回到同一个地方。 Much will depend on exactly what you want to see happen in this case. 在这种情况下,很大程度上取决于您想要看到的内容。

In the end my general rule of thumb in storyboard was: 最后,我在故事板中的一般经验法则是:

0) In the App delegate, work out the type of device and set the root screen to be the correct storyboard controller entrypoint: eg split view on ipad, tab view on iPhone. 0)在App委托中,计算设备类型并将根屏幕设置为正确的故事板控制器入口点:例如,在ipad上拆分视图,在iPhone上选项卡视图。 It is handy to add some methods/properties to the app delegate for any controller to access to find out the current running mode. 将任何方法/属性添加到app委托以便任何控制器访问以找出当前运行模式是很方便的。 This will make life easier later when you need to decide which segue to fire. 当你需要决定开火时,这将使生活更轻松。

1) Create individual controllers as required and always use Any/Any size class design view to create the bulk of the design. 1)根据需要创建单独的控制器,并始终使用任意/任何大小的类设计视图来创建大部分设计。 I started using different design views but found that got too tricky to manage. 我开始使用不同的设计视图,但发现管理起来太棘手了。 Especially as some controllers could appear in popovers where the size class on iPad (compact width) in not the same as when on the main screen (regular width). 特别是因为一些控制器可能出现在弹出窗口中,其中iPad上的尺寸等级(紧凑宽度)与主屏幕上的尺寸等级(常规宽度)不同。

2) Use size class adjustments for individual constraints, fonts etc as required. 2)根据需要对各个约束,字体等使用大小等级调整。

3) For any view controller which may appear in a popover, precede it with a UINavigationController with a storyboard Id that can be used as the root of any popover. 3)对于任何可能出现在弹出窗口中的视图控制器,在它前面加上一个UINavigationController,其故事板ID可以用作任何弹出框的根。

4) For UISplitViewControllers create as normal using showDetail style segues. 4)对于UISplitViewControllers,使用showDetail样式segues正常创建。

5) For UIViewControllers which are used as detail views in split view controllers, but which may also need to be pushed on when used in a popover or on iPhone on iOS7, create push segues from their respective master detail controllers. 5)对于在分割视图控制器中用作详细视图的UIViewControllers,但是当在弹出窗口或iOS7上的iPhone上使用时也可能需要将其推入,从其各自的主细节控制器创建推送segue。 You only need this if you every present content designed in a split view via a popover or when on iOS7 which has no split view on iPhone. 如果您通过弹出窗口在拆分视图中设置的每个现有内容,或者在iPhone上没有拆分视图的iOS7上,您只需要这个。

6) Create segues between your controllers, including iPad/iPhone specific segues. 6)在控制器之间创建segue,包括iPad / iPhone特定的segues。 You can use storyboard activation if there is only one possible segue. 如果只有一个可能的segue,您可以使用storyboard激活。 Otherwise simply draw the segues between the controllers themselves. 否则只需在控制器本身之间绘制segue。

7) For any controllers where buttons or cells trigger segues, you add target actions rather than segue triggers. 7)对于按钮或单元格触发segues的任何控制器,您可以添加目标操作而不是segue触发器。 In these actions you will call the appropriate segue manually. 在这些操作中,您将手动调用相应的segue。

8) In each view controller where a destination controller type is dependent on the type of display mode, write code which uses your app delegate run mode properties to make a decision on which segue to use and then call peformSegueWithIdentifier with the identifier of the segue. 8)在每个视图控制器中,目标控制器类型取决于显示模式的类型,编写代码,使用您的app委托运行模式属性来决定使用哪个segue,然后使用segue的标识符调用peformSegueWithIdentifier

Non of this is particularly pretty but it seems a necessary evil, especially if you use split view controllers and popovers. 不是这个特别漂亮,但它似乎是一个必要的邪恶,特别是如果你使用拆分视图控制器和弹出窗口。 The good thing is that you can at least see everything in one place. 好处是你至少可以在一个地方看到一切。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM