3

我的应用程序同时使用横向模式和纵向模式,用户可以随意在两者之间切换。

当视图控制器由纵向的父视图控制器呈现时,打开的视图控制器将具有正确的宽度和框架

但是,如果父视图控制器处于横向模式,那么在 IOS6 上(它在 IOS7 上正常工作),子视图控制器会太大,而且在呈现时实际上也有点太短。

请注意,这不是因为值报告不正确,因为 [[UIScreen mainScreen] bounds] 报告相同的值,无论子控制器加载的方向如何。

关于如何解决这个问题/为什么会发生这种情况的任何想法?关于如何强制 IOS6 版本表现得像 IOS7 现在的任何想法?非常感谢!!!

编辑:: 以下是 vc 的呈现方式:

应用委托

Launch1 *launch1 =[[Launch1 alloc] init];
self.window.rootViewController = launcher;
[self.window makeKeyAndVisible];

发射1类

Search *search = [[Search alloc] init];
[self presentViewController:search animated:YES completion:nil];

搜索类

//load list_container
views = [[Search_custom_views alloc] initWithControllerContext:self];
[self.view addSubview:views];

Search_custom_views UIView 扩展:

- (id)initWithControllerContext:(UIViewController*)contextstart {

    //set size of the screen
    CGRect screenRect = [[UIScreen mainScreen] bounds];

    self = [super initWithFrame:screenRect];

    if (self) {
     ....
4

2 回答 2

2

所以这是一个艰难的过程。我以编程方式加载所有视图。它们基本上是对应于每个视图控制器的 UIView 子类。出于某种原因,当从父视图控制器以横向模式打开 IOS6 视图控制器时,子视图控制器的边界不会立即传递给子 vc 的 UIView 子类(如果您只是在控制器的 viewDidLoad 方法中使用 addSubview--那还不够)。IOS7没有这个问题。

对我来说 IOS6 的修复是在子视图控制器的 viewDidLoad 方法中执行以下操作:

//add view subclass to view controller
[self.view addSubview:views];

//reset bounds & refresh layout for IOS6
if ([[[UIDevice currentDevice] systemVersion] floatValue] < 7) {
    views.frame = self.view.bounds;
    [views layoutIfNeeded];
}
于 2013-10-25T13:16:41.617 回答
0

iOS 7 喜欢它,[[UIScreen mainScreen] bounds]而不是[[UIScreen mainScreen] applicationFrame]因为 applicationFrame 属性在不同版本的 iOS 之间的计算不一致,而 bounds 是。

它应该是向后兼容的,因此您应该能够执行以下操作:

- (CGRect)filterBankFrameForOrientation:(UIInterfaceOrientation)orientation {
    CGRect appFrame = [[UIScreen mainScreen] bounds];
    if (UIInterfaceOrientationIsLandscape(orientation)) {//using bounds here instead of applicationFrame for iOS7 compatibility
        //Handle landscape orientation
        filterBankFrame = CGRectMake(0.0, k_filterBankOffsetFromTop, appFrame.size.height, k_filterBankHeight);
    }
    else {
        //Handle portrait orientation
        filterBankFrame = CGRectMake(0.0, k_filterBankOffsetFromTop, appFrame.size.width, k_filterBankHeight);
    }
    return filterBankFrame;
}

并根据需要简单地翻转高度和宽度值(因为边界将始终处于“纵向”方向)

使用bounds应该为您提供跨 iOS 版本和设备尺寸的相同行为所需的一致性。

更新以响应 OP 的更新代码

我建议您至少考虑的一种方法是在 InterfaceBuilder 中连接这些视图并使用 AutoLayout 为您担心旋转。它还有一个额外的好处,那就是优雅地处理所有可用的不同屏幕尺寸,所以这也很好。

尽管如此,在代码中创建和管理这一切也是完全可以接受的,并且可能是适合您情况的正确选择。如果是这样,您将需要覆盖UIViewController. 可能大部分或所有这些:

– shouldAutorotate
– supportedInterfaceOrientations
– preferredInterfaceOrientationForPresentation
– willRotateToInterfaceOrientation:duration:
- didRotateFromInterfaceOrientation

至少第一个和最后两个。

为了避免只在启动时被绑定到一个方向,这是一种常见的设计模式(需要引用)来编写我上面发布的方法,然后从这两个viewDidLoad方法以及willRotate / didRotate类方法中使用它。

在 viewDidLoad 期间调用时,您执行以下操作:

_filterBank.collectionView.frame = [self filterBankFrameForOrientation:[[UIApplication sharedApplication] statusBarOrientation]];

它使用该statusBarOrientation属性以横向或纵向正确启动。

willRotate / didRotate两种方法都为您提供了一个参数,您可以将其传递给您的帧生成方法。

您的方法为您提供了正确的帧大小,然后由您来传递此信息并相应地操作您的视图层次结构。这比听起来容易...

(在你的情况下,它看起来launcher会实现这些方法,然后协调调整到launch1,然后再下降到search最后到Search_custom_views

(**最后附注,你会在这里结交更多的朋友,SearchCustomViews而不是选择Search_custom_views

于 2013-10-24T21:01:14.807 回答