【问题标题】:How to load specific storyboard depending on device in Objective C? [duplicate]如何根据Objective C中的设备加载特定的故事板? [复制]
【发布时间】:2021-01-04 19:14:01
【问题描述】:

这是一个转发,因为另一个已关闭。

我在自动布局方面遇到了麻烦,所以我只想制作两个故事板,iPad 和 iPhone。我想要的只是检测它的设备类型或大小,然后显示他们尊重的故事板。我已经尝试了在 StackOverflow 上找到的几乎所有解决方案,但我无法让它发挥作用。

目前,我在 DidFinishLaunchingWithOptions 下的 AppDelegate.m 上检测到设备的大小,然后加载情节提要并设置 initialViewController。当我运行 iPad 模拟器时,它会正确运行并显示,并在控制台中返回正确的故事板和视图控制器。但是,当我运行 iPhone 模拟器时,它会显示 iPad 故事板,但在控制台中,它显示它返回了 iPhone 故事板和正确的初始视图控制器。

另外,我是 Objective-C 的新手,但已经掌握了窍门。谢谢,希望有人可以帮忙。 这是我的 App Delegate 代码。

#import "AppDelegate.h"

@interface AppDelegate ()

@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    // Override point for customization after application launch.
    UIStoryboard *storyboard = self.window.rootViewController.storyboard;
    UIViewController *rootViewController;
    
    // detect screen height
    int height = [UIScreen mainScreen].fixedCoordinateSpace.bounds.size.height;
    NSLog(@"The fixed height is %i", height);
    
    // determine if this is an iPad
    if (UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad) {
        
        // it's an iPad
        if (height >= 1024) {
            
            storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
            rootViewController = [storyboard instantiateViewControllerWithIdentifier:@"loginViewController"];
            
            NSLog(@"LOADING MAIN/IPAD STORYBOARD");
        }
        
    } else {
        // it's an iPhone
        storyboard = [UIStoryboard storyboardWithName:@"iPhone" bundle:nil];
        rootViewController = [storyboard instantiateViewControllerWithIdentifier:@"iPhoneLoginViewController"];
        
        NSLog(@"LOADING IPHONE STORYBOARD");
    }
    
    NSLog(@"Root View Controller: %@", rootViewController);
    NSLog(@"Storyboard: %@", storyboard);
    
    self.window.rootViewController = rootViewController;
    [self.window makeKeyAndVisible];
    
    return YES;
}
#pragma mark - UISceneSession lifecycle


- (UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options {
    // Called when a new scene session is being created.
    // Use this method to select a configuration to create the new scene with.
    return [[UISceneConfiguration alloc] initWithName:@"Default Configuration" sessionRole:connectingSceneSession.role];
}


- (void)application:(UIApplication *)application didDiscardSceneSessions:(NSSet<UISceneSession *> *)sceneSessions {
    // Called when the user discards a scene session.
    // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
    // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}

@end   

这是我的 Info.plist:

Info.plist Property List

    <key>UILaunchStoryboardName</key>
    <string>LaunchScreen</string>
    <key>UIMainStoryboardFile</key>
    <string>Main</string>
    <key>UIMainStoryboardFile~ipad</key>
    <string>Main</string>
    <key>UIMainStoryboardFile~iphone</key>
    <string>iPhone</string>
    <key>UIRequiredDeviceCapabilities</key>

以下是 iPad VS iPhone 结果的截图:

iPad Simulator with its correct storyboard

iPhone Simulator showing incorrect storyboard

iPhone Storyboard

【问题讨论】:

  • 能否提供源代码?
  • 我建议您对 iPhone 和 iPad 使用相同的类 (h&m) 以实现可重复性。在不同的故事板中没有问题
  • 您需要发布 SceneDelegate 和 AppDelegate 的完整代码,以便我们看到您在做什么。作为旁注 - 您展示的图像可以通过自动布局和单个故事板轻松管理。
  • 整个项目的源码?好一点,我将为两者使用相同的课程。谢谢! @AnisMansuri
  • 我添加了整个 App Delegate 代码。另外,对于 SceneDelegate 我并没有搞砸它。它是空的。我需要在那里配置一些东西吗?是的,我会再次尝试进行自动布局。谢谢! @DonMag

标签: ios objective-c xcode uistoryboard


【解决方案1】:

您不必检测任何东西。 Info.plist 本身将安排运行时加载不同的故事板,具体取决于这是否是 iPad。有一个简单的命名约定来管理这种行为:只需在 Info.plist 中创建另一个以 ~ipad 结尾的键。

因此,如果您想拥有两个不同的主故事板,请使用 Info.plist 命名约定:配置两个“主故事板文件基本名称”键,UIMainStoryboardFileUIMainStoryboardFile~ipad — 或,对于 iOS 13 及更高版本下的窗口场景,配置两个“Application Scene Manifest”键,UIApplicationSceneManifestUIApplicationSceneManifest~ipad,指定不同的 UISceneStoryboardFile 值。

【讨论】:

  • 您好,感谢您的回复!我在另一个 StackOverflow 帖子中看到了这一点,我也尝试过,我只是添加了 Info.plist 的图像和源代码。让我知道这是否正确。
  • 我不明白为什么它是正确的。你没有按照我说的去做。正如我所说,您有一个应用程序场景清单。你需要两个。
  • 哇,非常感谢!抱歉,由于误解,我以为您的意思是我正在做的 UIMainStoryboardFile 。我为 iPad 添加了第二个 UIApplicationScene Manifest,它现在可以工作了。成就了我的一天。有一个好兄弟!
猜你喜欢
  • 2014-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-18
  • 2023-01-19
  • 2017-09-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多