使用SDAutoLayout实现控件根据内容进行宽度自适应和高度自适应

简介: 使用SDAutoLayout实现控件根据内容进行宽度自适应和高度自适应

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》

目录
相关文章
|
消息中间件 运维 负载均衡
【Kafka】Kafka 实现负载均衡与故障转移
【4月更文挑战第5天】【Kafka】Kafka 实现负载均衡与故障转移
|
9月前
|
IDE 测试技术 开发工具
Xcode 16.4 (16F6) 发布 - Apple 平台 IDE
Xcode 16.4 (16F6) 发布 - Apple 平台 IDE
970 1
Xcode 16.4 (16F6) 发布 - Apple 平台 IDE
|
8月前
|
开发者
HarmonyOS NEXT实战:网络图片加载和失败占位图
本教程介绍如何在HarmonyOS应用中实现网络图片加载时显示加载图、加载完成后显示图片、加载失败时显示占位图的功能。内容涵盖Image组件的alt、onComplete、onError等接口使用,适用于教育和实战开发场景。
332 0
|
8月前
|
机器学习/深度学习 人工智能 自然语言处理
2025人工智能证书|2025年人工智能行业AI证书如何选择?
在2025年AI浪潮中,生成式AI已成为职场核心竞争力。企业招聘将“AI能力”设为基础门槛,如何选择有价值的AI认证?本文从行业趋势、证书价值、备考策略及职业规划四大维度解析。GAI认证由培生推出,涵盖核心技术与实际应用,结合理论与实践考核,助力职业发展。它不仅评估技术能力,还注重伦理法律等复合技能。备考需分阶段规划,善用官方资源,注重实践。无论转型、深耕还是管理晋升,GAI认证均适合作为起点,抢占AI时代先机。
|
11月前
|
存储 弹性计算 安全
ECS与VPS技术角力:从算力成本到免备案雷区,企业服务器选型合规指南
在数字化浪潮中,服务器选择至关重要。ECS(云服务器)和VPS(虚拟专用服务器)是热门选项。ECS基于云计算,提供高可用性和弹性伸缩,适合大型项目;VPS通过分割物理服务器实现资源独立,成本较低,适合小型应用。两者在网络、存储及计算性能上各有优劣,需根据需求选择。国内并不存在合法的免备案服务器,建议严格遵守法规,确保网站合法运营。
547 3
|
人工智能 Cloud Native 大数据
云+AI开启算力新时代,共建开源开放生态赴未来 | 2024龙蜥大会主论坛
本次分享的主题是云 + AI开启算力新时代,共建开源开放生态赴未来 | 2024龙蜥大会主论坛,由阿里巴巴集团合伙人、阿里云基础设施事业部总经理蒋江伟分享。
277 6
修改了代码,但是不想提交应该怎么设置呢
在开发过程中,为了防止本地调试时修改的配置文件被误提交,可以采用以下方法:先点击“commit”,然后右键选择“Move to Another Changelist”,并为新变更列表命名。提交时忽略该列表即可避免误提交。
Mac卸载 Node npm,升级 Node
Mac卸载 Node npm,升级 Node
321 0
UITableView顶部突然出现一块空白问题
UITableView顶部突然出现一块空白问题
UITableView根据表格内容进行高度自适应与使用Masonry实现根据内容进行宽度自适应和高度自适应
UITableView根据表格内容进行高度自适应与使用Masonry实现根据内容进行宽度自适应和高度自适应
359 0