这里上接这篇文章,经过前期的准备,这里终于开始使用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的高度变化,但可以重新布局适应不同屏幕。