问题描述
我在自动布局方面遇到麻烦,所以我只想制作两个故事板,iPad和iPhone。我想要的只是检测设备的类型或大小,然后显示其受尊重的情节提要。我已经尝试了在StackOverflow上找到的几乎所有解决方案,但无法使其正常工作。
当前,我在DidFinishLaunchingWithOptions下的AppDelegate.m上检测设备的大小,然后加载情节提要并设置initialViewController。当我运行iPad模拟器时,它会运行并正确显示,并在控制台中返回正确的情节提要和视图控制器。但是,当我运行iPhone模拟器时,它会显示iPad故事板,但在控制台中会显示它返回了iPhone故事板和正确的initialviewcontroller。
此外,我是Objective-C的新手,但是掌握了它。谢谢,希望有人能帮忙。 这是我的应用程序委托代码。
#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:
<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
解决方法
您不必检测任何东西。 Info.plist 本身将根据是否是iPad来安排运行时加载不同的故事板。有一个简单的命名约定可以控制此行为:只需在 Info.plist 中输入另一个以~ipad
结尾的键即可。
因此,如果要使用两个不同的主故事板,请使用 Info.plist 命名约定:配置两个“主故事板文件库名称”键,UIMainStoryboardFile
和{{1 }} —或者,对于iOS 13及更高版本下的窗口场景,配置两个“应用程序场景清单”键UIMainStoryboardFile~ipad
和UIApplicationSceneManifest
,它们指定不同的UIApplicationSceneManifest~ipad
值。