iPad ios8上不同方向的不同布局

时间:2014-09-21 11:48:50

标签: objective-c ios7 migration ios8

对于我的应用程序,我设计了一个包含两个子视图的视图,这些子视图在设备旋转时更改了它们的位置。即,它们在纵向视图中并且在水平方向上并排堆叠。我为ios7编写的代码完美无缺。迁移到ios8后,我无法再次使用它。当首先出现时,视图将正确显示,但在旋转或从其他屏幕返回之后,似乎两个视图都在屏幕外呈现(我在动画期间看到它)。我无法弄清楚我在这里做错了什么。日志对于无法满足的约束保持沉默。

我的代码与显示,约束和轮换相关:

    - (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
    {
        [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {
            UIInterfaceOrientation o = size.height > size.width ? UIInterfaceOrientationPortrait : UIInterfaceOrientationLandscapeLeft;
            [self updateLayoutWithOrientation:o];
        } completion:nil];
        [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
    }

    - (void)viewWillAppear:(BOOL)animated
    {
        [super viewWillAppear:animated];
        [self updateLayoutWithOrientation:[[UIApplication sharedApplication] statusBarOrientation]];
    }

    - (void)updateLayoutWithOrientation:(UIInterfaceOrientation)o
    {
        [self.view removeConstraints:self.view.constraints];
        if (UIInterfaceOrientationIsPortrait(o)) {
            [self setDetailsAndGalleryViewsConstraints:@"V:|-[galleryView(<=664)]-[detailsView]-|"];
            [self setGalleryViewConstraint:@"H:|-[galleryView]-|"];
            [self setDetailsViewConstraint:@"H:|-[detailsView]-|"];
        } else {
            [self setDetailsAndGalleryViewsConstraints:@"H:|-[galleryView(==664)]-[detailsView]-|"];
            [self setGalleryViewConstraint:@"V:|-[galleryView]-|"];
            [self setDetailsViewConstraint:@"V:|-[detailsView]-|"];
        }
    }

    - (void)setGalleryViewConstraint:(NSString *)format
    {
        [self setConstraint:format onView:self.view views:NSDictionaryOfVariableBindings(galleryView);];
      }

    - (void)setDetailsViewConstraint:(NSString *)format
    {
        [self setConstraint:format onView:self.view views:NSDictionaryOfVariableBindings(detailsView)];
    }

    - (void)setDetailsAndGalleryViewsConstraints:(NSString *)format
    {
        [self setConstraint:format onView:self.view views:NSDictionaryOfVariableBindings(galleryView, detailsView)];
    }
    - (void)setConstraint:(NSString *)format onView:(UIView *)targetView views:(NSDictionary *)views
    {
         [targetView addConstraints:[NSLayoutConstraint
                           constraintsWithVisualFormat:format
                           options:NSLayoutFormatDirectionLeadingToTrailing
                           metrics:nil
                           views:views
                           ]];
    }

更新

关于@sha建议我在运行时检查了约束。修改了一些代码,看看如何翻译关系:

[self setDetailsAndGalleryViewsConstraints:@"V:|-(1)-[galleryView(<=664)]-(2)-[detailsView]-(3)-|"];
[self setGalleryViewConstraint:@"H:|-(4)-[galleryView]-(5)-|"];
[self setDetailsViewConstraint:@"H:|-(6)-[detailsView]-(7)-|"];

结果是:

Runtime constraints in inspector

让我感到惊讶的是,第一个视图的top指定了两次,一次是超级视图,然后是它的兄弟。然而,我不知道是否有预期,如果不是,如何解决它。

更新

我试图手动设置布局并使用尺寸类,但看起来iPad有规则的宽度和常规高度,因此无法对某些方向进行更改。试图在没有运气的情况下覆盖特征集合

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
    // tried it also in coordinator:animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> method
    [self updateLayoutWithOrientation:size];
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    [self updateLayoutWithOrientation:self.view.bounds.size];
}

- (void)updateLayoutWithOrientation:(CGSize)screenSize
{
    NSArray *traitArray;
    if (screenSize.height > screenSize.width) {
        traitArray = [NSArray arrayWithObjects:
                      [UITraitCollection traitCollectionWithVerticalSizeClass:UIUserInterfaceSizeClassRegular],
                      [UITraitCollection traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassRegular],
                      nil];
    } else {
        traitArray = [NSArray arrayWithObjects:
                      [UITraitCollection traitCollectionWithVerticalSizeClass:UIUserInterfaceSizeClassCompact],
                      [UITraitCollection traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassRegular],
                      nil];
    }

    UITraitCollection *traits = [UITraitCollection traitCollectionWithTraitsFromCollections:traitArray];
    [self setOverrideTraitCollection:traits forChildViewController:self];
}

1 个答案:

答案 0 :(得分:3)

我也在与iOS 8中的约束作斗争(在iOS 7中没有问题)

我发现了这个电话

[self.view removeConstraints:self.view.constraints];

不会删除所有约束!

最后,为了解决我的问题并删除所有警告,我玩了约束优先级。通过这种方式,我不需要删除任何约束,我也不会收到任何警告。希望这可以提供帮助。