使用不等式约束和优先级限制UICollectionView高度

时间:2016-02-29 19:22:43

标签: objective-c autolayout nslayoutconstraint

我有一个固定到其超视图底部,左边和右边的集合视图,以及一个固定在顶视图,左视图和右视图的文本字段。随着更多项目的添加,集合视图的高度在updateConstraints从下向上增加,并根据其内容大小设置高度约束。

我希望收藏视图的高度增长但不超过 在它上面的textField的底部有一个不等式约束 集合视图的顶部边缘。以下是我尝试过的内容:

self.topResistanceConstraint = [NSLayoutConstraint constraintWithItem:self.collectionView
    attribute:NSLayoutAttributeTop
    relatedBy:NSLayoutRelationGreaterThanOrEqual
    toItem:self.textField
    attribute:NSLayoutAttributeBottom
    multiplier:1.0
    constant:0];
[self addConstraint:self.topResistanceConstraint];

CGSize size = self.collectionView.collectionViewLayout.collectionViewContentSize;

self.heightConstraint = [NSLayoutConstraint constraintWithItem:self.collectionView
attribute:NSLayoutAttributeHeight
    relatedBy:NSLayoutRelationEqual
    toItem:nil
    attribute:NSLayoutAttributeNotAnAttribute
    multiplier:1.0
    constant:size.height];
[self addConstraint:self.heightConstraint];

这导致不满足的约束,并且恢复(并且实际上似乎有效),但它不是一个好的解决方案,并且如果布局需要适应键盘出现或消失,则不起作用。有关如何创建约束或优先级以使其在不破坏约束的情况下工作的任何建议吗?

2 个答案:

答案 0 :(得分:1)

经过一些试验和错误后,只需将heightConstraint设置为低优先级即可。 topResistanceConstraint的优先级是必需的,并且可以防止集合视图的顶部超出文本字段的底部。

self.heightConstraint = [NSLayoutConstraint constraintWithItem:self.collectionView attribute:NSLayoutAttributeHeight
    relatedBy:NSLayoutRelationEqual
    toItem:nil
    attribute:NSLayoutAttributeNotAnAttribute
    multiplier:1.0
    constant:size.height];

// set a low priority on height
self.heightConstraint.priority = UILayoutPriorityLow;

[self addConstraint:self.heightConstraint];

答案 1 :(得分:0)

此问题的首选解决方案是创建高度和顶部约束 (对于故事板中的collectionView,与#34; NSLayoutRelationGreaterThanOrEqual"相关的顶部约束)并为两者创建出口。 之后获取collectionView项目计数,然后动态计算collectionView的高度,如下所示

NSInteger count = 5;
CGFloat collectionViewHeight = count/2 * cellHeight; // for collectionView with two(2) columns
CGFloat maxCollectionViewHeight = CGRectGetHeight(self.view.frame) - CGRectGetHeight(self.textField.frame) - CGRectGetMaxY(self.textField.frame);
if (collectionViewHeight < maxCollectionViewHeight ) {
    self.heightConstraint.constant = collectionViewHeight;
} else {
    self.topConstraint.constant = 20; // Min spacing between two views;
}