我有一个在iPad和iPhone上运行的通用应用程序。应用程序以.xib文件开始,该文件内置于界面构建器中,该文件充当启动映像。应用程序启动后,会根据应用程序委托中设置的设备大小切换到相应的视图控制器:
CGSize screenSize = [[UIScreen mainScreen] bounds].size;
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
if (screenSize.height <= 568.0f) {
// iPhone 4, 4S, 5, 5C, 5S, SE
self.viewController = [[iPhoneSmallViewController alloc] init];
} else {
// All other iPhones
self.viewController = [[iPhoneLargeViewController alloc] init];
}
} else {
// All iPad models
self.viewController = [[iPadViewController alloc] init];
}
iPad视图控制器支持所有界面方向(在app目标/主设置页面中设置),但在iPhone上我只允许在视图控制器中限制纵向模式:
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
return (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown);
}
这个方法有两个问题:
我使用窗口的大小通过在ViewDidLoad方法中初始化以下变量来设置视图中的所有内容:
windowSize = [[UIScreen mainScreen] bounds].size;
即使不允许横向模式,Tt也会让我在手机中横向保持横向尺寸。
问题:有没有人能够以优雅和简单的方式处理这个复杂的问题?
一些额外的信息:我使用Xcode 10,支持一直回到iOS9并在Objective C中以编程方式完成所有操作。
p.s:我认为这种方法之前有效,但在iOS 12中已经不再适用了。但我可能错了......
编辑:我提供了我想要完成的图像,所有的帮助将不胜感激。正如我所说,这已经有效了(应用程序已经很老了),但是在最近的iOS版本中,越来越多的越野车越来越需要清理,这是我需要帮助的。
可能解决我的问题的一件事是,如果我可以在launchScreen.xib中基于设备类型以某种方式限制接口方向,因为我认为这是导致iPhone上的错误行为的原因。
也许这个SO会有所帮助,他们正在检测设备方向,然后旋转视图,看看第一个答案:
Change orientation programmatically with button - iOS
UIInterfaceOrientation currentOrientation = [UIApplication sharedApplication].statusBarOrientation;
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
[[UIDevice currentDevice] setValue:value forKey:@"orientation"];
[UIViewController attemptRotationToDeviceOrientation];
这里解释了检测设备的更好方法:iOS detect if user is on an iPad
if ( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad )
{
return YES; /* Device is iPad */
}
我已经试验了好几天了,并找到了解决方案。虽然这可能不是最优雅的方式,但如果有人有更好的解决方案,请随时发布。
此时,手机可以处于info.plist中设置的四个界面方向中的任意一个,但由于只有小手机具有320宽度,因此很容易捕获它:
// Get screen size
CGSize screenSize = [[UIScreen mainScreen] bounds].size;
// Determine device based on screen dimensions
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
if ( (screenSize.height == 320.0f) || (screenSize.width == 320.0f) ){
// iPhone 4, 4S, 5, 5C, 5S, SE
self.viewController = [[iPhoneSmallViewController alloc] init];
} else {
// iPhone 6, 6S, 6P, 6SP, 7, 7P, 8, 8P X, XS, XM, XR
self.viewController = [[iPhoneLargeViewController alloc] init]; //Same as previous
}
} else {
// All iPad models
self.viewController = [[iPadViewController alloc] init];
}
这样做:
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return (UIInterfaceOrientationMaskPortrait);
}
因此,为了防止错误行为,您需要创建一个单独的方法来进行设置(例如postViewDidLoad)并在真正的viewDidLoad结束后调用它:
- (void) viewDidLoad
{
[super viewDidLoad];
[self performSelector:@selector(postViewDidLoad) withObject:nil afterDelay:0.0f];
}
在此方法中,您将根据在supportedInterfaceOrientations方法中设置的限制来访问实际屏幕大小。
这基本上就是这样。如果您有多个视图,但都有不同的限制,请按照每个视图中的步骤4和5来正确设置工作流程。