如何以编程方式在 UICollectionView 上添加自动布局?

How to add auto layout on UICollectionView programmatically?

我以编程方式创建了一个 uicollectionview,我想在集合视图上添加自动布局约束,以便稍后更改框架。但是下面的代码是行不通的。

我正在尝试像这样初始化集合视图:

        self.rootCollectionView = [[UICollectionView alloc]initWithFrame:CGRectMake(0, 100, self.bounds.size.width, self.bounds.size.height - 100) collectionViewLayout:[[UICollectionViewFlowLayout alloc]init]];
        self.rootCollectionView.dataSource = self;
        self.rootCollectionView.delegate = self;
        self.rootCollectionView.backgroundColor = [UIColor clearColor];
        [self addSubview:self.rootCollectionView];
        [self.rootCollectionView registerClass:[CASlideSwitchViewCell class] forCellWithReuseIdentifier:@"CASlideSwitchViewCell"];
        self.topConstraint = 100;
        float topCon = self.topConstraint;//self.topConstraint is a CGFloat property,
        UICollectionView * cv = self.rootCollectionView;
        cv.translatesAutoresizingMaskIntoConstraints = NO;
        NSArray * constraintArray = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[cv]-0-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(cv)];
        NSArray *constraintArray2 = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-topCon-[cv]-0-|" options:0 metrics:@{@"topCon":@(topCon)} views:NSDictionaryOfVariableBindings(cv)];
        [self addConstraints:constraintArray];
        [self addConstraints:constraintArray2];

然后在收到数据后,我尝试根据数据更改 topConstraint。像这样:

if (number <= 1) {
    self.topScrollView.hidden = YES;
    self.topConstraint = 0;
}else{
    self.topScrollView.hidden = NO;
    self.topConstraint = 100;
}
[self updateConstraints];
[self.rootCollectionView.collectionViewLayout invalidateLayout];
[self.rootCollectionView reloadData];

但是,UICollectionView 的上边距始终为 100。

我错过了什么吗?或者这样添加自动布局是不对的?

self.topConstraint 是一个浮点数而不是 NSLayoutConstraint,所以你不能更新约束。您可以不使用

NSArray *constraintArray2 = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-topCon-[cv]-0-|" options:0 metrics:@{@"topCon":@(topCon)} views:NSDictionaryOfVariableBindings(cv)];

你应该使用

NSLayoutConstraint *topLayoutContraint = [NSLayoutConstraint constraintWithItem:cv
                             attribute:NSLayoutAttributeTop
                             relatedBy:NSLayoutRelationEqual
                                toItem:self
                             attribute:NSLayoutAttributeTop
                            multiplier:1.0
                              constant:100];

NSArray *constraintArray2 = @[
                              topLayoutContraint,
                              [NSLayoutConstraint constraintWithItem:cv
                                                           attribute:NSLayoutAttributeBottom
                                                           relatedBy:NSLayoutRelationEqual
                                                              toItem:self
                                                           attribute:NSLayoutAttributeBottom
                                                          multiplier:1.0
                                                            constant:0]
                              ];

那你可以

if (number <= 1) {
    self.topScrollView.hidden = YES;
    topLayoutContraint.constant = 0;
} else {
    self.topScrollView.hidden = NO;
    topLayoutContraint.constant = 100;
}

[self setNeedsLayout];
[self.rootCollectionView reloadData];