场景 - 根据 iPad 或 iPhone 使用专用故事板
Posted
技术标签:
【中文标题】场景 - 根据 iPad 或 iPhone 使用专用故事板【英文标题】:Scenes - Use dedicated Storyboards depending iPad or iPhone 【发布时间】:2021-07-07 22:51:24 【问题描述】:Apple 现在希望我们使用“场景”而不是窗口和屏幕来显示 iPad 和 iPhone 的内容。现在添加了对场景的支持后,我似乎无法使用 Storyboard 定位 iPad 或 iPhone?
我将我的场景设置在 plist 中,如下所示:
这是从一个新项目中复制的,因为 Apple 似乎忘记记录如何将场景添加到现有应用程序。 Apple 没有充分记录的另一个例子!
现在我似乎失去了在 iPhone 上为 iPad 使用不同故事板的能力。
虽然我可以在 iPad 上使用与 iPhone 相同的故事板,但我的应用程序在 iPad 专用界面上看起来更好,因为我使用它提供的额外空间来提供更好的最终用户体验。 iPhone 很好,界面最适合小显示器,但在 iPad 上看起来很贫瘠。
救命!
【问题讨论】:
【参考方案1】:现在我似乎失去了在 iPhone 上为 iPad 使用不同故事板的能力
这很简单(而且,正如你所说,没有记录)。您的 Info.plist 中需要两个完全独立的场景清单条目,即 UIApplicationSceneManifest
和 UIApplicationSceneManifest~ipad
。他们只是指定了不同的UISceneStoryboardFile
值,而你的一切都和场景出现之前一样。
【讨论】:
试图将 UIApplicationSceneManifest~ipad 添加到 plist 中,它似乎不想接受它作为场景。你如何添加它并确保它指向正确的场景清单? 我知道这行得通,因为我已经做到了。除非它已经停止工作。 :( 让我快速开始,稍等。 是的,它工作正常。我会为你在 GitHub 上发布一个示例...... 给你:github.com/mattneub/TwoStoryboards 我同意,您的方法很有趣,并且您提供它作为您自己问题的答案的方式在 SO 上完全有效【参考方案2】:可能有更好的方法来做到这一点,但搜索我看不到其他人涵盖了这一点。因此,我在这里提供已被 App Store 接受的解决方案,供其他人查看、使用、改进,最重要的是,不要浪费任何时间去寻找可能不存在的解决方案!
我解决这个问题的方法是添加另一个故事板和视图控制器来处理决定是 iPhone 还是 iPad,然后立即加载目标故事板。我称之为“进入决定”。唯一的问题是在关闭后续视图时,您必须确保您正确地执行此操作,否则您最终会回到“进入决定”。如果使用空白视图,您的最终用户可能会被卡住。因此,为了确保用户永远不会真正被卡住,我在该视图中放置了按钮,以便他们可以手动导航,如果 Apple 进一步做出我们不知道的更改,他们可以手动导航。最好现在就覆盖它。
第 1 步,创建一个新的故事板,“进入决策”:
因为我是一个好人,所以我向用户解释这是一个错误并道歉。我还给了他们两个按钮,iPad 和 iPhone。从理论上讲,如果一切顺利,最终用户将永远不会看到这一点,但我们最好免费覆盖这种可能性。
第 2 步,一旦加载视图控制器,就让它移动到我们真正想要的正确故事板。
-(void)viewDidLoad
// Need to decide which storyboard is suitable for this particular method.
// Loading from class: https://***.com/questions/9896406/how-can-i-load-storyboard-programmatically-from-class
if ( [UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad )
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard_iPad" bundle:nil];
ViewController *detailViewController = [storyboard instantiateViewControllerWithIdentifier:@"myViewController"];
[self.navigationController pushViewController:detailViewController animated:YES];
else
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
ViewController *detailViewController = [storyboard instantiateViewControllerWithIdentifier:@"myViewController"];
[self.navigationController pushViewController:detailViewController animated:YES];
- (IBAction)pickediPhone:(id)sender
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
ViewController *detailViewController = [storyboard instantiateViewControllerWithIdentifier:@"myViewController"];
[self.navigationController pushViewController:detailViewController animated:YES];
- (IBAction)pickediPad:(id)sender
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard_iPad" bundle:nil];
ViewController *detailViewController = [storyboard instantiateViewControllerWithIdentifier:@"myViewController"];
[self.navigationController pushViewController:detailViewController animated:YES];
这并没有什么特别之处,因为它混合了检测哪个设备,然后加载正确的故事板。为了全面披露,我引用了我用于加载这些故事板的原始代码。
另外两种方法只是按下按钮,为了完整起见,此处显示。
第 3 步,更新 plist 中的场景配置以针对 Entry Decision 而不是 Main。
您的目标是不同的故事板,因此需要更新。
第 4 步,返回主屏幕。
在我的应用程序中,我有一个欢迎屏幕,然后是表格视图或其他视图,具体取决于它是什么。某些类型可以正常工作,但由于我使用的是导航控制器,因此我需要正确返回。因此,这个最适合最终“返回”到主屏幕的命令:
[self.navigationController popViewControllerAnimated:YES];
其他选项要么回到进入决策(我们为以防万一)或什么都不做:
[self.navigationController popToRootViewControllerAnimated:YES];
[self dismissViewControllerAnimated:YES completion:NULL];
这就是我能够使用现有故事板的方式,这些故事板在这个应用程序的生命周期中已经针对 iPhone 和 iPad 进行了完美调整,并且仍然能够支持 Apple 转向场景的愿望。我的应用程序需要将场景用于其他目的,因此我别无选择,只能走这条路。我经历了许多尝试来尝试在场景加载时捕获场景,但初始场景似乎在没有您(程序员)的情况下加载,无法获得任何关于它应该如何或使用哪个选项的选项。您需要这个预览控制器来恢复该功能,它是目前在 App Store 中活跃的一种解决方案。
做个好人。
【讨论】:
以上是关于场景 - 根据 iPad 或 iPhone 使用专用故事板的主要内容,如果未能解决你的问题,请参考以下文章
根据浏览器内核判断是web/iOS/android/ipad/iphone 来打开不同的网站或页面
当我从 iPad 切换到 iPhone 在 xcode 上“查看为”时,一个场景仍然看起来像 iPad