【问题标题】:Selecting different storyboards based on device type根据设备类型选择不同的故事板
【发布时间】:2013-01-18 06:48:45
【问题描述】:

我有一个通用应用程序,我在 application:didFinishLaunchingWithOptions 中手动加载我的主故事板。

我有 2 个用于 iPhone 和 iPad 的故事板,它们具有 ~iPhone~iPad 后缀。我正在加载我的故事板:

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
self.initialViewController = [storyboard instantiateInitialViewController];

这会将Unknown class ViewController in Interface Builder file. 打印到控制台,因此显然它没有加载正确的情节提要。但是,当我使用 [UIStoryboard storyboardWithName:@"MainStoryboard~iPhone" bundle:nil]; 时,它可以正常工作,但当然只适用于 iPhone。

我错过了什么?如何使用名称后缀自动选择正确的情节提要?

【问题讨论】:

  • 你为什么不去项目设置,在 iphone 部署信息中设置 iphone 的故事板,在 ipad 部署信息中设置 ipad 的故事板。您是否在每台设备上使用多个故事板?我的意思是你手动加载故事板的目的是什么?
  • 我要做的是将 IIViewDeckController 设置为根视图控制器,因此自动加载情节提要没有帮助。
  • 这似乎是某些版本中的错误(对我来说,它在 iOS 6.1.2 中被破坏,但它在同一个项目的早期工作)。根据 Apple 文档,~iphone 后缀是通用的,应该会影响它们的所有资源加载(图像、NIB 文件 - 在我以前的经验中,一切)。故事板似乎坏了,不知何故跳过了选择器。

标签: iphone ios uistoryboard


【解决方案1】:

我不知道根据文件名后缀自动选择情节提要。您可以使用userInterfaceIdiom 来选择 iPad 还是 iPhone:

if ([[UIDevice currentDevice] userInterfaceIdiom] ==UIUserInterfaceIdiomPad) {
    UIStoryboard *storyboard = 
    [UIStoryboard storyboardWithName:@"MainStoryboard_iPad" bundle:nil];
} else {
    [UIStoryboard storyboardWithName:@"MainStoryboard_iPhone" bundle:nil];
}

但是如果你这样做是为了启动一个特定的视图控制器,你需要做的就是将“开始”箭头拖到故事板中你喜欢的视图控制器

或者 - 选择故事板中的视图控制器,转到属性检查器并勾选isInitialViewController

【讨论】:

  • 我认为情节提要会根据 XIB 文件和图像等文件名后缀自动选择。谢谢!
  • 您可以向 UIStoryboard 添加一个类别,例如 deviceStoryboardWithName:bundle:,它将封装此代码并附加适当的后缀,然后调用 storyboardWithName:bundle:。这将使代码更易于阅读和遵循。
  • 您可以在 info.plist 中为 iPhone 和 iPad 设置单独的故事板。这是我的原始输出: UIMainStoryboardFileMainUIMainStoryboardFile~ipadiPad 所以有一个单独的键用于设置iPad 故事板。我的配置中对应的文件名是 Main.storyboard 和 iPad.storyboard。
【解决方案2】:

这是您可以直接在 info.plist 文件中设置的另一项内容。无需任何编程工作。查找名为 'Main storyboard file base name' 的属性,默认情况下将在其中包含 'Main'

您可以添加另一个名为 'Main storyboard file base name (iPad)' 的属性,该属性随后将用于 iPad。

plist 中的原始输出如下所示:

<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UIMainStoryboardFile~ipad</key>
<string>iPad</string>

Afaik 也可以简单地添加第二个名为 Main~iPad.storyboard 的故事板(如果 UIMainStoryboardFile 键设置为 Main)。这将被用于 iPad。不过好久没测试了。

【讨论】:

  • 这是最简单的答案,适用于 xcode v9.4.1
  • 这是要走的路
【解决方案3】:

// 在appdelegate类中,启动应用时选择指定的故事板。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
        UIStoryboard *storyboard1;

    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
    {
        storyboard1 = [UIStoryboard storyboardWithName:@"Main_iPhone" bundle:[NSBundle mainBundle]];
    }
    else if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
    {
        storyboard1 = [UIStoryboard storyboardWithName:@"Main_iPad" bundle:[NSBundle mainBundle]];
    }
    UIViewController *vc = [storyboard instantiateInitialViewController];

    // Set root view controller and make windows visible
    self.window.rootViewController = vc;
    [self.window makeKeyAndVisible];

    return YES;
}

【讨论】:

    【解决方案4】:

    你可以这样命名你的故事板

    • Main.storyboard(适用于 iPhone)
    • Main_iPad.storyboard(适用于 iPad)

    然后像这样选择它们

    - (UIStoryboard *)deviceStoryboardWithName:(NSString *)name bundle:(NSBundle *)bundle {
        if (IS_IPAD) {
            NSString *storyboardIpadName = [NSString stringWithFormat:@"%@_iPad", name];
            NSString *path = [[NSBundle mainBundle] pathForResource:storyboardIpadName ofType:@"storyboardc"];
    
            if (path.length > 0) {
                return [UIStoryboard storyboardWithName:storyboardIpadName bundle:bundle];
            }
        }
    
    
        return [UIStoryboard storyboardWithName:name bundle:bundle];
    }
    

    【讨论】:

      猜你喜欢
      • 2014-03-30
      • 2014-11-07
      • 2016-07-20
      • 2015-11-15
      • 1970-01-01
      • 2016-05-31
      • 1970-01-01
      • 2023-01-19
      • 2022-11-10
      相关资源
      最近更新 更多