SDAutoLayout
github地址 https://github.com/gsdios/SDAutoLayout
SDAutoLayout的自适应宽度和高度大致可以分为三类情况。
第一种情况:控件根据内容进行宽度自适应:
_infoLabel.sd_layout
.leftSpaceToView(self, 0)
.bottomSpaceToView(self, 0)
.heightIs(13); // 设置高度约束
[_infoLabel setSingleLineAutoResizeWithMaxWidth:(40)];
当然若你的控件是先加载控件,后填入内容就需要在重置内容后对控件进行重新布局:
[_infoLabel updateLayout];
[_distanceLabel updateLayout];
注意:SDAutoLayout是延迟布局生效,不是你刚调用.sd_layout对控件进行布局后立即填充内容,它的宽度就是刚布局时的宽度。但是若控件已经加载出来,等大约1秒后你再对它赋值,那么你不对它重新布局,那么它显示的就是最开始的宽度。高度自适应也是如此。
第二种情况:非表格控件根据内容进行高度自适应。
子控件(GBPayHeadPanel)布局函数部分代码:
_smallTitleLabel.sd_layout
.leftSpaceToView(self, 30)
.rightSpaceToView(self, 30)
.topSpaceToView(self, 36)
.autoHeightRatio(0); // 设置高度约束
[self setupAutoHeightWithBottomView:_smallTitleLabel bottomMargin:0];
父页面(GBEstimatePayDetailsViewController)布局函数部分代码:
//头部信息
_payHeadPanel.sd_layout
.leftSpaceToView(self.view, 0)
.rightSpaceToView(self.view, 0)
.topSpaceToView(self.view, shiftHeight)
.autoHeightRatio(0); // 设置高度约束
第三种情况:表格控件根据内容进行高度自适应,不但要对控件进行自适应高度,还要对表格高度进行高度计算,对表格高度进行重新复制,并且采用表格复用的删除表格内容的方式复用。
表格加载代码:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
GBMyOrderListContentCell *cell = nil;
cell = [tableView dequeueReusableCellWithIdentifier:cellWithIdentifier];
if (!cell) {
cell = [[GBMyOrderListContentCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellWithIdentifier];
}
else//当页面拉动的时候 当cell存在并且最后一个存在 把它进行删除就出来一个独特的cell我们在进行数据配置即可避免
{
while ([cell.contentView.subviews lastObject] != nil) {
[(UIView *)[cell.contentView.subviews lastObject] removeFromSuperview];
}
cell = [[GBMyOrderListContentCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellWithIdentifier];
}
if([self.tripManageEntity.orderList isKindOfClass:[NSMutableArray class]] && (self.tripManageEntity.orderList.count > 0))
{
cell.model = [_tripManageEntity.orderList objectAtSafeIndex:indexPath.section];
}
return cell;
}
表格高度计算代码(注意这个计算高度的地方别都传整个屏幕的宽度,要传你的这个自适应控件的宽度,不然可能多算高度):
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
GBOrderListEntity *orderListEntity = nil;
if([self.tripManageEntity.orderList isKindOfClass:[NSMutableArray class]] && (self.tripManageEntity.orderList.count > 0))
{
orderListEntity = [self.tripManageEntity.orderList objectAtSafeIndex:indexPath.section];
}
else
{
orderListEntity = nil;
}
return [tableView cellHeightForIndexPath:indexPath model:orderListEntity keyPath:@"model" cellClass:[GBMyOrderListContentCell class] contentViewWidth:FULL_WIDTH - SMALL_EDGE_DISTANCE*2];
}
表格控件布局函数部分代码:
-(void)unitsSdLayout
{
//大背景
_alertBackgroundView.sd_layout
.leftSpaceToView(self.contentView, 0)
.rightSpaceToView(self.contentView, 0)
.topSpaceToView(self.contentView, 0)
.autoHeightRatio(0);
_myOrderListHeadCell.sd_layout
.leftSpaceToView(self.alertBackgroundView, 15)
.rightSpaceToView(self.alertBackgroundView, 15)
.topSpaceToView(self.alertBackgroundView, 20)
.heightIs(14); // 设置高度约束
_startAddressLabel.sd_layout
.leftSpaceToView(self.alertBackgroundView, 34)
.topSpaceToView(_myOrderListHeadCell, 19)
.rightSpaceToView(self.alertBackgroundView, 15)
.autoHeightRatio(0);
_startIconImageView.sd_layout
.leftSpaceToView(self.alertBackgroundView, 15)
.centerYEqualToView(_startAddressLabel)
.widthIs(8)
.heightIs(8); // 设置高度约束
_endAddressLabel.sd_layout
.leftSpaceToView(self.alertBackgroundView, 34)
.topSpaceToView(_startAddressLabel, 5)
.rightSpaceToView(self.alertBackgroundView, 15)
.autoHeightRatio(0);
_endIconImageView.sd_layout
.leftSpaceToView(self.alertBackgroundView, 15)
.centerYEqualToView(_endAddressLabel)
.widthIs(8)
.heightIs(8); // 设置高度约束
_bottomWholeLineView.sd_layout
.leftSpaceToView(self.alertBackgroundView, 15)
.rightSpaceToView(self.alertBackgroundView, 15)
.topSpaceToView(self.endAddressLabel, 19)
.heightIs(YX_1PX); // 设置高度约束
_infoLabel.sd_layout
.leftSpaceToView(self.alertBackgroundView, 15)
.topSpaceToView(self.bottomWholeLineView, 12)
.widthIs(200)
.heightIs(13); // 设置高度约束
UIImage *arrowImage = [UIImage imageNamed:@"gbusecar_common_icon_entrance"];
_arrowIconView.sd_layout
.rightSpaceToView(self.alertBackgroundView, 15)
.centerYEqualToView(_infoLabel)
.widthIs(arrowImage.size.width)
.heightIs(arrowImage.size.height); // 设置高度约束
//
[self.alertBackgroundView setupAutoHeightWithBottomView:self.endAddressLabel bottomMargin:67];
[self setupAutoHeightWithBottomView:self.alertBackgroundView bottomMargin:0];
}
第一种:
控件根据内容进行宽度自适应完整代码:
-(void)unitsSdLayout
{
_infoLabel.sd_layout
.leftSpaceToView(self, 0)
.bottomSpaceToView(self, 0)
.heightIs(13); // 设置高度约束
[_infoLabel setSingleLineAutoResizeWithMaxWidth:(40)];
_distanceLabel.sd_layout
.leftSpaceToView(_infoLabel, 0)
.rightSpaceToView(self, 0)
.bottomSpaceToView(self, 0)
.heightIs(13); // 设置高度约束
_iconImageView.sd_layout
.rightSpaceToView(self, 0)
.centerYEqualToView(_infoLabel)
.widthIs(5)
.heightIs(10); // 设置高度约束
_descriptionLabel.sd_layout
.rightSpaceToView(_iconImageView, 6)
.centerYEqualToView(_infoLabel)
.widthIs(120)
.heightIs(13); // 设置高度约束
}
- (void)setModel:(ODCTripListEntity *)model
{
_model = model;
if(model.endPoint.distance <= 0)
{
_distanceLabel.text = @"--公里";
}
else if(model.endPoint.distance < 1000)
{
_distanceLabel.text = [NSString stringWithFormat:@"%.f米", model.endPoint.distance];
}
else
{
_distanceLabel.text = [NSString stringWithFormat:@"%.3f公里", model.endPoint.distance/1000];
}
_descriptionLabel.hidden = NO;
_iconImageView.hidden = NO;
[_infoLabel updateLayout];
[_distanceLabel updateLayout];
}
第二种情况:非表格控件根据内容进行高度自适应的完整代码。
GBPayHeadPanel子控件:
-(void)unitsSdLayout;
{
_titleLabel.sd_layout
.leftSpaceToView(self, 30)
.topSpaceToView(self, 0)
.widthIs(180) // 设置宽度约束
.heightIs(36); // 设置高度约束
if(_payDetailsEntity.isShowSmallTitle)
{
_smallTitleLabel.sd_layout
.leftSpaceToView(self, 30)
.rightSpaceToView(self, 30)
.topSpaceToView(self, 36)
.autoHeightRatio(0); // 设置高度约束
[self setupAutoHeightWithBottomView:_smallTitleLabel bottomMargin:0];
}
}
GBEstimatePayDetailsViewController页面的布局函数:
-(void)unitsSdLayout
{
CGFloat shiftHeight = (FULL_HEIGHT - 36 - 66 - YX_1PX*2 - [self getTabviewHeight] - 26 -20)/2;//(long)(170 *FULL_HEIGHT/667);
if(self.payDetailsEntity.isShowSmallTitle)
{
//头部信息
_payHeadPanel.sd_layout
.leftSpaceToView(self.view, 0)
.rightSpaceToView(self.view, 0)
.topSpaceToView(self.view, shiftHeight)
.autoHeightRatio(0); // 设置高度约束
}
else
{
//头部信息
_payHeadPanel.sd_layout
.leftSpaceToView(self.view, 0)
.rightSpaceToView(self.view, 0)
.topSpaceToView(self.view, shiftHeight)
.heightIs(36); // 设置高度约束
}
}
另外在UILabel自适应高度的同时,也可以对UILabel显示的最大行数进行限制,代码如下:
[self.productNameLabel setMaxNumberOfLinesToShow:2];
更简单的实现自适应高度和宽度见《使用Masonry实现控件(包括UITableView)根据内容进行宽度自适应和高度自适应》和《自适应高度的表格UICollectionView》。