自动布局以编程方式修改约束乘数

auto layout modify multiplier of constraint programmatically

如何以编程方式修改约束的乘数?我设置了以下内容:

[self.view addConstraint:[NSLayoutConstraint constraintWithItem:_button attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeWidth multiplier:0.5 constant:0.0]];

我需要将其修改为:

[self.view addConstraint:[NSLayoutConstraint constraintWithItem:_button attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeWidth multiplier:1.0 constant:0.0]];

您将无法更改乘数,因为它是只读的。您必须存储对约束的引用。然后,当您想要更改乘数时,您将删除约束并添加一个新约束。

您可以在视图控制器实现中包含这样的方法:

- (void)changeMultiplier:(NSLayoutConstraint **)constraint to:(CGFloat)newMultiplier{
    NSLayoutConstraint *newConstraint = [NSLayoutConstraint constraintWithItem:(*constraint).firstItem attribute:(*constraint).firstAttribute relatedBy:(*constraint).relation toItem:(*constraint).secondItem attribute:(*constraint).secondAttribute multiplier:newMultiplier constant:(*constraint).constant];
    [self.view removeConstraint:(*constraint)];
    [self.view addConstraint:newConstraint];
    *constraint = newConstraint;
}

相关问题:

Can i change multiplier property for NSLayoutConstraint?

正如其他人所说,你必须删除旧的并添加一个新的。如果您不想将其存储为属性,只需设置标识符并稍后搜索即可

-(NSLayoutConstraint *)constraintWithIndientifer:(NSString *)identifer InView:(UIView *)view{
    NSLayoutConstraint * constraintToFind = nil;
    for (NSLayoutConstraint * constraint in view.constraints ) {
        if([constraint.identifier isEqualToString:identifer]){
            constraintToFind = constraint;
            break;
        }
    }
    return constraintToFind;
}

然后

NSLayoutConstraint * constraint = [NSLayoutConstraint constraintWithItem:self.yellowView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeWidth multiplier:0.5 constant:0.0];
constraint.identifier = @"1234";
[self.view addConstraint:constraint];

那你就可以得到这个

NSLayoutConstraint * constraint = [self constraintWithIndientifer:@"1234" InView:self.view];

为了修改乘数,我使用了在约束之间切换的方法。
您必须创建具有不同优先级的约束,否则它会破坏布局。

Objective C

NSLayoutConstraint *constraint1, *constraint2;

// switch between constraints

constraint1.active = NO; 
constraint2.active = YES;
[self.view layoutIfNeeded];

Swift 2.0

self.constraint1.active = true
self.constraint2.active = false
self.view.layoutIfNeeded()

有一种更简单的方法可以使用 Layout Anchors:

以编程方式修改约束的乘数
imageView.heightAnchor.constraint(equalTo: imageView.widthAnchor, multiplier: 1.0/2.0).isActive = true

工作原理如下:

简单的答案,不需要扩展。我尝试过我的情况,对我来说效果很好。

因为乘数是一个只能获取的属性,我们可以简单地通过以下方式设置乘数:

yourConstraintOutlet.setValue(yourDesiredMultiplierValue, forKey: "multiplier")

yourConstraintOutlet.setValue(0.75, forKey: "multiplier")

不需要扩展,也不需要乘以 superview height/width。