IOS 6视图控制器的宽度/边界不正确 - 横向模式

时间:2013-10-24 20:43:14

标签: ios iphone objective-c

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

当视图控制器由处于纵向方向的父视图控制器呈现时,打开的视图控制器将具有正确的宽度&帧

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

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

关于如何解决这个/为什么会发生这种情况的任何想法?关于如何强制IOS6版本像IOS7一样的任何想法现在都是本机行为?非常感谢!!!

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

的AppDelegate

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

Launch1类

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) {
     ....

2 个答案:

答案 0 :(得分: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];
}

答案 1 :(得分:0)

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

它应该是向后兼容的,所以你应该能够做到这样的事情:

- (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使用它_filterBank.collectionView.frame = [self filterBankFrameForOrientation:[[UIApplication sharedApplication] statusBarOrientation]]; 类方法。

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

statusBarOrientation

使用willRotate / didRotate属性以横向或纵向正确启动。

launcher方法都为您提供了一个可以传递给帧生成方法的参数。

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

(在您的情况下,看起来launch1会实施这些方法,然后将调整协调为search,然后调整为Search_custom_views,最后调整为SearchCustomViews)< / p>

(**最后一面注意事项,选择Search_custom_views代替{{1}},你会在这里结识更多朋友)