NSLayoutConstraints代码将视图居中并保持其纵横比

dan*_*anh 6 iphone ios autolayout

我希望我的子视图是一个16:9的矩形,位于其超视图的顶部.换句话说,我希望它:

  1. 和它的超视图一样宽,但不超过400px(UI可以旋转到横向),
  2. 当它比它的超视图更窄时水平居中,
  3. 把它的顶部固定在它的超级视图顶部,并且
  4. 改变它的高度以保持16:9的宽高比.

这个代码几乎可以做到,除了我很难使水平约束工作而不是过度或受限制......

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.

    UIView *contentView = [[UIView alloc] init];
    contentView.backgroundColor = [UIColor redColor];
    [self.view addSubview:contentView];

    contentView.translatesAutoresizingMaskIntoConstraints = NO;

    NSDictionary *views = NSDictionaryOfVariableBindings(contentView);
    NSMutableArray *constraints = [NSMutableArray array];

    // this layout string is more like 'wishful coding'.  I don't see why it wouldn't work
    // but clearly this one is the problem
    [constraints addObjectsFromArray:[NSLayoutConstraint
                                      constraintsWithVisualFormat:@"H:|-(>=0)-[contentView(<=400)-(>=0)-]"
                                      options:0 metrics:0 views:views]];

    // this centering constraint below almost does the job, but doesn't give me a way
    // to specify width, changing the one above to just @"H:[contentView(<=400)]"
    // doesn't work either
    [constraints addObject:
     [NSLayoutConstraint constraintWithItem:contentView
                                  attribute:NSLayoutAttributeCenterY
                                  relatedBy:NSLayoutRelationEqual
                                     toItem:self.view
                                  attribute:NSLayoutAttributeCenterY
                                 multiplier:1.f constant:0.f]];

    // 9:16 works fine, I think
    [constraints addObject:
     [NSLayoutConstraint constraintWithItem:contentView
                                  attribute:NSLayoutAttributeHeight
                                  relatedBy:NSLayoutRelationEqual
                                     toItem:contentView attribute:NSLayoutAttributeWidth
                                 multiplier:9.0/16.0 constant:0.0]];

    // pin the tops works fine, I think
    [constraints addObjectsFromArray:
     [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[contentView]"
                                             options:0 metrics:0 views:views]];

    [self.view addConstraints:constraints];
}
Run Code Online (Sandbox Code Playgroud)

Fir*_*eer 16

如果要将红色框水平居中,则需要将视图等同于CenterX,而不是CenterY.所以约束应该如下所示:

[NSLayoutConstraint constraintWithItem:contentView
                             attribute:NSLayoutAttributeCenterX
                             relatedBy:NSLayoutRelationEqual
                                toItem:self.view
                             attribute:NSLayoutAttributeCenterX
                            multiplier:1.f constant:0.f]];
Run Code Online (Sandbox Code Playgroud)

然后在第一个约束条件下,您在那里的约束是不明确的,因为有不止一种方法来满足>=0每边和<=400宽度的边距.更好的办法是说正是你在你的问题,这是说,你需要的宽度为<= 400,你会喜欢的利润率可能的话为0.

所以像这样:

[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(0@900)-[contentView(<=400)]-(0@900)-|"
                                        options:0 metrics:0 views:views]];
Run Code Online (Sandbox Code Playgroud)

我相信你想要你想要的吗?