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

3
我该如何以编程方式修改约束的乘数?我已经设置了以下内容:
[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]];

我认为没有改变乘数的方法,但是您可以删除限制并设置新的限制。 - almas
在这里回答了 https://dev59.com/omIk5IYBdhLWcg3wG6o6 - user3125367
我最终使用了常量而不是乘数。 - Jason Bestor
5个回答

5

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

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

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

相关问题:

我能改变NSLayoutConstraint的乘数属性吗?


谢谢,我简直不敢相信这个问题没有出现在我的搜索结果中。也许我只是粗略地看过它。 - Jason Bestor
我该如何传递约束条件?这将使得实现更清晰明了。 - TheJeff

4

我使用约束切换的方法来修改倍增器。
您必须创建具有不同优先级的约束,否则会破坏布局。

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()

3

如其他人所说,您需要删除旧的并添加新的。如果您不想将其存储为属性,只需设置标识符和搜索以后获取它即可。

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

1
谢谢您的建议。最终我使用了常量,以保持简单...self.constraint = [NSLayoutConstraint constraintWithItem:_button attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:(self.view.frame.size.width / 2)]; [self.view addConstraint:_newsWidthConstraint];然后稍后我将其编辑为全宽...self.constraint.constant = self.view.frame.size.width; - Jason Bestor

2

使用布局锚点可以更轻松地以编程方式修改约束的乘数:

imageView.heightAnchor.constraint(equalTo: imageView.widthAnchor, multiplier: 1.0/2.0).isActive = true

这是它的工作原理:
点击这里查看演示。

这对我来说很容易就解决了。我认为这是最简单的方法。 - Guru Dev

0

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

因此,由于乘数是只读属性,我们可以通过以下方式简单地设置乘数:

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

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

不需要任何扩展,并且不需要乘以父视图的高度/宽度。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接