0

我对 xCode 4.5 的新自动布局功能感到很困惑。

这是我想做的,

通过设置故事板,我设置了这个纵向视图。 在此处输入图像描述

通过使用自动布局和约束(和引脚),当布局像这样翻转为横向时,如何转换布局? 在此处输入图像描述

我尝试在景观化时编码和更改视图的 CGRect(大小和坐标位置),但无济于事。

4

2 回答 2

2

NSLayoutConstraints 取代了自动布局中对 CGRects 的需求。首先,用文字描述你的布局。以下是我如何描述您的肖像示例:

  • Red 的宽度是其 superview 的 60%。
  • Blue 的高度是其 superview 的 55%。
  • 蓝色的左右边缘正在触及它的超级视图。
  • 红色的左边缘接触其父视图,红色的右边缘靠近黄色的左边缘,黄色的右边缘接触其父视图。
  • 蓝色的上边缘接触其父视图,蓝色的下边缘靠近红色的上边缘,红色的下边缘接触其父视图。
  • 蓝色的下边缘接近黄色的上边缘,黄色的下边缘接触它的超级视图。

这是一种删除superview现有约束的方法,然后为给定的界面方向应用新的约束。

- (void) buildConstriantsForInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // Remove existing constraints.
    [superview removeConstraints:superview.constraints] ;
    // Build an array to hold new constraints.
    NSMutableArray* constraints = [NSMutableArray new] ;

    // Add 2 constraints that apply to both Portrait & Landscape orientations.
    [constraints addObject:[NSLayoutConstraint constraintWithItem:red  attribute:NSLayoutAttributeWidth  relatedBy:NSLayoutRelationEqual  toItem:superview  attribute:NSLayoutAttributeWidth  multiplier:0.6  constant:0]] ;
    [constraints addObject:[NSLayoutConstraint constraintWithItem:blue  attribute:NSLayoutAttributeHeight  relatedBy:NSLayoutRelationEqual  toItem:superview  attribute:NSLayoutAttributeHeight  multiplier:0.55  constant:0]] ;

    // Build a dictionary to store references to NSViews.
    NSDictionary* views = NSDictionaryOfVariableBindings(superview, blue, red, yellow) ;
    // To eliminate repeated NSLayoutConstraint code, build an array of Format Strings with which to build constraints.
    NSArray* formatStrings ;
    if ( UIInterfaceOrientationIsPortrait(interfaceOrientation) ) {
        formatStrings = @[@"H:|[blue]|", @"H:|[red]-[yellow]|", @"V:|[blue]-[red]|", @"V:[blue]-[yellow]|"] ;
    }
    else {
        formatStrings = @[@"H:|[blue]-[yellow]|", @"H:|[red]-[yellow]", @"V:|[blue]-[red]|", @"V:|[yellow]|"] ;
    }

    for ( NSString* formatString in formatStrings ) {
        [constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:formatString  options:0  metrics:nil  views:views]] ;
    }

    // Add the newly created constraints.
    [superview addConstraints:constraints] ;
}

每当视图加载或旋转时,您都可以调用该方法。

-(void) viewDidLoad {
    superview.translatesAutoresizingMaskIntoConstraints = NO ;
    [self buildConstriantsForInterfaceOrientation:self.interfaceOrientation] ;
}

- (void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    [self buildConstriantsForInterfaceOrientation:toInterfaceOrientation] ;
}
于 2013-05-24T15:46:13.370 回答
1

自动布局非常擅长表达一个对象与另一个对象的关系并解决冲突 - 但它没有内置任何条件概念。对于您的布局,我认为您可能会发现添加和删除旋转约束最简单,请查看https: //developer.apple.com/library/ios/#documentation/AppKit/Reference/NSLayoutConstraint_Class/NSLayoutConstraint/NSLayoutConstraint.html有关如何添加这些的详细信息。

您还可以设置约束并调整优先级,以便在轮换时做正确的事情,但需要进行一些测试和调整才能正确执行。我在本地进行了一些测试,我认为我的做法是正确的,但这只是使用没有固有内容大小的空视图。尽管如此,我认为通过情节提要完成这一切所需的内容如下:

  • 确保蓝色视图的宽度 <= 纵向宽度和 >= 最小横向宽度
  • 确保红色视图具有最小高度
  • 修复黄色视图的宽度,并将高度设置为 >= 纵向高度
  • 将每个视图锚定到它将始终保留的角落(例如,将尾随和底部固定到黄色的超级视图)
  • 将黄色视图的顶部与蓝色视图对齐,优先级低
  • 增加黄色的内容抗压缩性

我认为它从具有相当高优先级最大尺寸的蓝色视图开始,而黄色视图知道如何向上扩展但优先级较低。当它旋转时,蓝色视图保持其最大尺寸,从而释放黄色视图向上扩展。然后我填写所需的约束以保持对齐。

这在文本中描述起来相当复杂,这里是一个屏幕截图,显示了三个视图和它们之间的约束。它并没有显示所有内容,但您至少可以检查视图之间的关系: xcode 显示约束

于 2013-05-24T15:46:04.293 回答