这里上接这篇文章,经过前期的准备,这里终于开始使用AutoLayout了,有了前面的铺垫这里才显得没那么唐突,好吧,这里先说下故事的背景吧,对于一个View,我们在布局的时候会写死它的大小,可能是(320,240),但是对于不同的屏幕尺寸,这样写显然是不合适的,对于一些简单的布局可以通过autoResizing的方式自动放大,但本例view中包含高度可变的CollectionView较为复杂,autoResizing已经不能满足我们的需求了,所以才转向更为强大的AutoLayout,可以说AutoResizing是AutoLayout的子集,AutoLayout使用起来更为复杂,但对于简单的问题,AutoResizing能够很简单的解决。
开始之前,我们可能还需要回顾下这篇文章,这里限制条件应该加在什么地方是个问题,
加在initWithFrame可以,但加在layoutSubviews中更合适,这样在addSubviews或者frame变化都会引起layoutSubviews的调用,先上一段计算当前布局高度和之前高度差值的函数
- (CGFloat)getRealAnimationViewHeightDt
{
NSArray* labels = [[MFAppModel sharedObject].chatroomModelEx getFullLabels];
NSInteger lineWidth = 50;
NSUInteger rowCount = 1;
for (int i = 1; i < labels.count; ++i) {
NSArray* labels = [[MFAppModel sharedObject].chatroomModelEx getFullLabels];
MFRoomLabel* currentRoomLabel = [labels objectAtIndex:i];
NSDictionary *attribute = @{NSFontAttributeName: [UIFont systemFontOfSize:15]};
CGSize currentLabelSize = [currentRoomLabel.name sizeWithAttributes:attribute];
CGFloat cellWidth = MAX(50, currentLabelSize.width + 16);
lineWidth = lineWidth + 15 + cellWidth;
if (lineWidth > (self.frame.size.width - 65)) {
rowCount++;
lineWidth = cellWidth;
}
}
return (rowCount - 2)*(24 + 10);
}
这里默认rowCount为2,对默认情况计算新的高度差值,来限制布局的大小。
这种代码写在哪里好?虽然是和UI相关的,但这里又夹杂着逻辑的数据,目前IOS开发中ViewController的使用还是比较迷惑,这里到底是放View还是也可以放些和UI相关的数据呢?这种破坏MVC模式的代码到底写在Model层还是View层?以后再讨论吧,这里先说AutoLayout的问题。
有了这个根据数据和当前屏幕尺寸计算出来的collectionView的dt值,就可以方便的加些约束条件了,这里首先你可以参考下这篇文章,这个例子很简单,都是受到加约束条件的最简单的用法,
下面上我们的代码
[self addConstraint:[NSLayoutConstraint
constraintWithItem:_collectionView
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeWidth
multiplier:0
constant:self.frame.size.width - 65]];
[self addConstraint:[NSLayoutConstraint
constraintWithItem:_collectionView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeHeight
multiplier:0
constant:_collectionView.frame.size.height + [self getRealAnimationViewHeightDt]]];
[self addConstraint:[NSLayoutConstraint
constraintWithItem:_mainView
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeWidth
multiplier:1
constant:0]];
[self addConstraint:[NSLayoutConstraint
constraintWithItem:_mainView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeHeight
multiplier:0
constant:_mainView.frame.size.height + [self getRealAnimationViewHeightDt]]];
[self addConstraint:[NSLayoutConstraint
constraintWithItem:_animationView
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeWidth
multiplier:1
constant:0]];
[self addConstraint:[NSLayoutConstraint
constraintWithItem:_animationView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeHeight
multiplier:0
constant:_animationView.frame.size.height + [self getRealAnimationViewHeightDt]]];
[self addConstraint:[NSLayoutConstraint
constraintWithItem:_buttonView
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeWidth
multiplier:1
constant:0]];
[self addConstraint:[NSLayoutConstraint
constraintWithItem:_cancelButton
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeWidth
multiplier:0.5
constant:0]];
[self addConstraint:[NSLayoutConstraint
constraintWithItem:_cancelButton
attribute:NSLayoutAttributeLeft
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeLeft
multiplier:1
constant:0]];
[self addConstraint:[NSLayoutConstraint
constraintWithItem:_okButton
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeWidth
multiplier:0.5
constant:0]];
[self addConstraint:[NSLayoutConstraint
constraintWithItem:_okButton
attribute:NSLayoutAttributeRight
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeRight
multiplier:1
constant:0]];
[self addConstraint:[NSLayoutConstraint
constraintWithItem:_buttonView
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:_lineView
attribute:NSLayoutAttributeBottom
multiplier:1
constant:0]];
[self addConstraint:[NSLayoutConstraint
constraintWithItem:_sortAndPositionLineView
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeWidth
multiplier:1
constant:0]];
[self addConstraint:[NSLayoutConstraint
constraintWithItem:_positionAndTagLineView
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeWidth
multiplier:1
constant:0]];
[self addConstraint:[NSLayoutConstraint
constraintWithItem:_lineView
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeWidth
multiplier:1
constant:0]];
[self addConstraint:[NSLayoutConstraint
constraintWithItem:_lineView
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:_mainView
attribute:NSLayoutAttributeBottom
multiplier:1
constant:0]];
[self addConstraint:[NSLayoutConstraint
constraintWithItem:_buttonLineView
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeCenterX
multiplier:1
constant:0]];
[self addConstraint:[NSLayoutConstraint
constraintWithItem:_lineView
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeWidth
multiplier:1
constant:0]];
想想这些约束条件要是加在IB中还能看吗?这也就是说AutoLayout复杂的地方,对于屏幕尺寸变化的情况,里面的所有view都需要根据这个最外层的屏幕尺寸而发生变化,再加上View中又有高度不可控的collectionView,真是约束的不亦乐乎,但回头想想,这也不失为一种解决问题的好办法,有没有更简单的解决问题的方法还有待挖掘,就目前对AutoLayout的理解,只能是这样的实现了
这个是不同屏幕尺寸的效果,可以看到,当屏幕分辨率小的时候,collectionView的高度变化,但可以重新布局适应不同屏幕。