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

时间:2013-08-14 03:36:13

标签: iphone ios autolayout

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

  1. 和它的超视图一样宽,但不超过400px(UI可以旋转到横向),
  2. 当它比它的超级视图更窄时水平居中,
  3. 将它的顶部固定在superview的顶部,
  4. 改变它的高度以保持16:9的宽高比。
  5. 这个代码几乎可以做到,除了我很难让水平约束工作而不会过度或不受限制......

    - (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];
    }
    

2 个答案:

答案 0 :(得分:16)

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

[NSLayoutConstraint constraintWithItem:contentView
                             attribute:NSLayoutAttributeCenterX
                             relatedBy:NSLayoutRelationEqual
                                toItem:self.view
                             attribute:NSLayoutAttributeCenterX
                            multiplier:1.f constant:0.f]];

然后在第一个约束上,你在那里的约束是不明确的,因为有多种方法可以在每一侧满足>=0边距,在宽度上满足<=400。更好的方法是准确地说出你在问题中所说的内容,即你需要宽度<= 400并且喜欢边距是如果可能,则为0。

这样的事情:

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

我相信这会让你想要吗?

答案 1 :(得分:0)

有时,我认为还有另一种解决方案,我在这里复制了我的解决方案。

如果你想要水平对齐,只需使用它 [parentView addConstraint:[NSLayoutConstraint constraintWithItem:subView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:parentView attribute:NSLayoutAttributeCenterX multiplier:1 constant:0]];

如果您想垂直对齐,只需使用它 [parentView addConstraint:[NSLayoutConstraint constraintWithItem:subView attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:parentView attribute:NSLayoutAttributeCenterY multiplier:1 constant:0]];

这个解决方案对我有用,我希望我能与其他人分享。