How to add auto layout on UICollectionView programmatically?

2.1k Views Asked by At

I create a uicollectionview programmatically, and I want to add auto layout constraint on the collection view so that I can change the frame later. But the following code is not work.

I am trying to initialize the collectionview like this:

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

then after I receive the data, I am trying to change topConstraint based on the data. Like this:

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

However, the top margin of the UICollectionView is always 100.

Do I miss something? Or it is not right to add auto layout like that?

1

There are 1 best solutions below

8
On BEST ANSWER

The self.topConstraint is a float not a NSLayoutConstraint so you can not update the constraint. You can instead of using

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

You should use

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

then you can

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

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