当前位置: 首页 > news >正文

【iOS】实现评论区展开效果

文章目录

  • 前言
  • 实现行高自适应
  • 实现评论展开效果
  • 解决cell中的buttom的复用问题


前言

在知乎日报的评论区中,用到了Masonry行高自适应来实现评论的展开,这里设计许多控件的约束问题,当时困扰了笔者许久,特此撰写博客记录

实现行高自适应

步骤1:
设置tableView.rowHeight = UITableViewAutomaticDimension

步骤2:
设置tableView.estimatedRowHeight = 100

解释:设置一个预估的行高,为了代码的易读性,还是尽量要设置一个跟cell的高差不多的值。

步骤3:
到了此步,就涉及到了我们行高自适应的核心思想:根据内容长短将我们的控件撑开从而实现tableviewcell撑开

方法便是对控件设置上下约束但是不设置其高度,这里需要注意我们的bottom的约束一定要与contentviewbottom有关,否则无法撑开我们的contentview

我们以一段小demo为例来讲解

    [_name mas_makeConstraints:^(MASConstraintMaker *make) {make.left.equalTo(@30);make.top.equalTo(@30);make.height.equalTo(@40);make.width.equalTo(@100);}];//    [_time mas_makeConstraints:^(MASConstraintMaker *make) {
//        make.left.equalTo(@30);
//            make.height.equalTo(@40);
//            make.width.equalTo(@100);
//        make.bottom.equalTo(self.contentView.mas_bottom).offset(-20);
//    }];[_content mas_makeConstraints:^(MASConstraintMaker *make) {make.left.equalTo(@30);make.top.equalTo(self->_name.mas_bottom).offset(10);
//            make.bottom.equalTo(self->_reply.mas_top).offset(-20);make.bottom.equalTo(self.contentView.mas_bottom).offset(-20);make.right.equalTo(self.contentView.mas_right).offset(-20);}];

当我们没有给_content的文本进行赋值时,视图层级是这样的
在这里插入图片描述
同时我们的_content控件甚至没有在层级图上出现,但是一旦我们对其进行赋值,就会自动撑开cell的高度

    cell.content.text = @"FMDB中有三个常用的类FMDatabase 表示一个SQLite数据库,用来执行SQL语句。";

在这里插入图片描述

实现评论展开效果

现在我们已经实现用Masonry实现行高自适应,接下来我们讲讲我们知乎日报评论区中评论的展开。
思路:
1.首先我们可以得到回复的一段文本,我们需要根据文本的长短来判断我们的评论是否需要展开,也就是说我们的展开效果是否需要实现是与我们评论的长短有关的。

-(CGSize)textHeightFromTextString:(NSString *)text width:(CGFloat)textWidth fontSize:(CGFloat)size {// 计算 label 需要的宽度和高度NSDictionary *dict = @{NSFontAttributeName:[UIFont systemFontOfSize:size]};CGRect rect = [text boundingRectWithSize:CGSizeMake(textWidth, MAXFLOAT) options:NSStringDrawingTruncatesLastVisibleLine|NSStringDrawingUsesFontLeading|NSStringDrawingUsesLineFragmentOrigin attributes:dict context:nil];CGSize size1 = [text sizeWithAttributes:@{NSFontAttributeName: [UIFont systemFontOfSize:size]}];return CGSizeMake(size1.width, rect.size.height);
}NSInteger count = [self textHeightFromTextString:reply width:303.667 fontSize:15.5].height /cell.replyLabel.font.lineHeight;if (count <= 2) {cell.foldButton.hidden = YES;} else {cell.foldButton.hidden = NO;}

这里需要注意,我们的回复label也需要实现行高自适应的效果,与content的代码结合起来便是

    [_name mas_makeConstraints:^(MASConstraintMaker *make) {make.left.equalTo(@30);make.top.equalTo(@30);make.height.equalTo(@40);make.width.equalTo(@100);}];[_time mas_makeConstraints:^(MASConstraintMaker *make) {make.left.equalTo(@30);make.height.equalTo(@40);make.width.equalTo(@100);make.bottom.equalTo(self.contentView.mas_bottom).offset(-20);}];[_content mas_makeConstraints:^(MASConstraintMaker *make) {make.left.equalTo(@30);make.top.equalTo(self->_name.mas_bottom).offset(10);make.bottom.equalTo(self->_reply.mas_top).offset(-20);make.right.equalTo(self.contentView.mas_right).offset(-20);}];[_reply mas_makeConstraints:^(MASConstraintMaker *make) {make.top.equalTo(self->_content.mas_bottom).offset(20);make.bottom.equalTo(self.time.mas_top).offset(-10);make.right.equalTo(self.contentView.mas_right).offset(-20);make.left.equalTo(@30);}];[_foldButton mas_makeConstraints:^(MASConstraintMaker *make) {make.left.equalTo(@140);make.height.equalTo(@40);make.bottom.equalTo(self.contentView.mas_bottom).offset(-20);make.width.equalTo(@100);}];

这样我们的contentreply就都与我们的contentView的底部又了约束关系,从而实现了行高自适应
在这里插入图片描述

解决cell中的buttom的复用问题

我们可以通过上面的动画看到,我们的评论区确实实现了评论展开,但是出现了buttom的复用问题,这里笔者将一下解决方案

  • 首先为每一个buttom设置一个tag值,并且我们需要通过我们的buttom得到我们的cell

笔者使用的方法是- (nullable __kindof UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath;

通过buttom的tag来确定我们的row,从而定位到我们选择的cell
replyTableViewCell *cell = (replyTableViewCell *)[_commentTableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:buttom.tag inSection:0]];

当然还有另外的办法,就是通过查找父视图的方法来得到对应的cell

 1.button.superView = cell.contentView; 2.button.superView.superView = cell; 3.button.superView.superView.superView = UITableviewWrapperView; 4.button.superView.superView.superView.superView = UITableView; 

这样一来就实现了得到对应buttom的cell

replyTableViewCell *cell = (replyTableViewCell *)[_commentTableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:buttom.tag inSection:0]];
replyTableViewCell *cell = (replyTableViewCell *)buttom.superview.superview;
  • 然后我们对对应的cellreply.numberOfLines进行修改
    if (cell.reply.numberOfLines == 0) {NSLog(@"1");cell.reply.numberOfLines = 2;[buttom setTitle:@" · 展示更多" forState:UIControlStateNormal];} else {NSLog(@"2");cell.reply.numberOfLines = 0;[buttom setTitle:@" · 收起" forState:UIControlStateNormal];}
  • 最后使用[_commentTableView beginUpdates]; [_commentTableView endUpdates];这两个方式刷新我们的tabelView

注意这里必须使用[_commentTableView beginUpdates];[_commentTableView endUpdates];,否则仍然会发生按钮的复用,原因是:

[_commentTableView reloadData]:

重新加载整个表格视图的数据。 此方法会重新调用数据源和代理方法,并刷新所有的行和部分。

[_commentTableView beginUpdates][_commentTableView endUpdates]:

用于执行一系列的插入、删除、选择和重新加载的动画,而不需要调用 reloadData。 通常与
insertRowsAtIndexPaths:withRowAnimation:、deleteRowsAtIndexPaths:withRowAnimation:、reloadRowsAtIndexPaths:withRowAnimation:
等方法一起使用。

UITableView 的 reloadData 方法会重新加载整个表格视图的数据,包括所有的行和部分。这会导致表格的重绘,所有的可见单元格都会被重新加载,也就是会调用 cellForRowAtIndexPath: 方法获取新的单元格。
如果在 cellForRowAtIndexPath: 方法中没有正确处理单元格的重用标识符和状态,就会导致按钮等子视图的状态混乱,因为这些子视图的状态没有被正确更新。
而使用 beginUpdates 和 endUpdates 方法执行一系列的插入、删除、选择和重新加载的操作时,系统会尽量保持现有单元格的状态,而不是重新加载整个单元格。这样,单元格的复用机制仍然有效,减少了对整个表格的重绘,从而减小了混乱的可能性。

同时使用[_commentTableView beginUpdates];[_commentTableView endUpdates];还优化了tableviewcell加载与刷新的性能开销

相关文章:

【iOS】实现评论区展开效果

文章目录 前言实现行高自适应实现评论展开效果解决cell中的buttom的复用问题 前言 在知乎日报的评论区中&#xff0c;用到了Masonry行高自适应来实现评论的展开&#xff0c;这里设计许多控件的约束问题&#xff0c;当时困扰了笔者许久&#xff0c;特此撰写博客记录 实现行高自…...

POE交换机——电源解决方案-升压控制器\降压控制器\中高压降压转换器

PoE是一种有线以太网供电技术&#xff0c;使用于数据传输的网线同时具备直流供电的能力&#xff0c;PoE供电具有可靠、连接简捷、标准统一的优势。越来越多的工业物联网设备开始采用PoE供电&#xff0c; 如IP电话、网络视频监控以及无线以太网设备等。 PoE交换机是一种用于提供…...

[C/C++]数据结构 循环队列

前言: 队列是一种具有先进先出特性的结构,但是当数据出队列以后,前面的空间就无法再次利用了,循环队列就可以解决这个问题 一:概念及结构: 1.循环队列概念 循环队列是一种线性数据结构&#xff0c;其操作表现基于 FIFO&#xff08;先进先出&#xff09;原则并且队尾被连接在队…...

Cache学习(2):Cache结构 命中与缺失 多级Cache结构 直接映射缓存

1 Cache名词解释 命中&#xff08;hit&#xff09;&#xff1a; CPU要访问的数据在Cache中有缓存缺失&#xff08;miss&#xff09;&#xff1a; CPU要访问的数据在Cache中没有缓存Cache Size&#xff1a;Cache的大小&#xff0c;代表Cache可以缓存最大数据的大小Cache Line&a…...

vue前端前端页面权限验证方式

在Vue应用中使用Vuex&#xff08;Vue的状态管理库&#xff09;来存储用户组&#xff08;user group&#xff09;和角色&#xff08;roles&#xff09;信息是一种合理的做法&#xff0c;特别是在涉及到权限管理和用户身份的情况下。Vuex提供了一个集中式的状态管理方案&#xff…...

jenkins springCloud项目优雅下线

文章目录 场景解决下线请求效果如图贴一个可用的部署脚本 场景 在 Spring Cloud 项目的微服务实例关闭时&#xff0c;需要首先从注册中心设置为下线&#xff0c;避免该服务的消费者继续请求该服务实例&#xff0c;导致请求失败如果我们在服务实例从注册中心取消注册后&#xff…...

indexOf

可以通過String的indexOf判斷是否包括某個字符。 SpringBootTest Slf4j class BaseApplicationTests {Testvoid contextLoads() {log.info("01".indexOf(".")"");log.info("0.1".indexOf(".")"");log.info("…...

STM32分区跳转问题

项目场景&#xff1a; 在OTA中&#xff0c;FLASH通常被划分为以下几种类型 bootloaderiapappbootloaderappapp保存区bootloaderapp1app2 不同的分区方式有不同的有点&#xff0c;但是共同点都是需要执行分区跳转 问题1描述 但在分区跳转过程中遇到过使用不同的编译器不能跳转…...

亿级流量架构服务降级

什么是服务降级 如果看过我前面对服务限流的分析,理解服务降级就很容易了,对于一个景区,平时随便进出,但是一到春节或者十一国庆这种情况客流量激增,那么景区会限制同时进去的人数,这叫限流,那么什么是服务降级呢? 简单来说就是,将一些不太重要的景区项目砍掉,平时就那么三五…...

【技术分享】RK3399 Ubuntu通过Python实现录音和播放功能

​本文基于IDO-SBC3968 Ubuntu 系统通过Python脚本实现录音和播放功能。 IDO-SBC3968采用RK3399国产六核64位CPU高性能处理器&#xff0c;支持4K HDMI2.0显示&#xff0c;接口丰富&#xff0c;拥有千兆以太网&#xff0c;全协议TypeC接口&#xff0c;USB3.0 &#xff0c;eDP 和…...

关于vs code Debug调试时候出现“找不到任务C/C++: g++.exe build active file” 解决方法

vs code Debug调试时候出现“找不到任务C/C: g.exe build active file” &#xff0c;出现报错&#xff0c;Debug失败 后来经过摸索和上网查找资料解决问题 方法如下 在Vs code的操作页面左侧有几个配置文件 红框里的是需要将要修改的文件 查看tasks.json和launch.json框选&…...

交叉导轨在光学工作台起什么重要作用?

光学工作台常常需要承载和移动各种光学元件和仪器&#xff0c;如望远镜、显微镜、光谱仪等&#xff0c;这些设备需要在空间中进行精确的定位和稳定支撑&#xff0c;而交叉导轨作为一种高精度、高刚度的直线传动元件&#xff0c;为光学工作台提供了重要的支撑和导向。 1>交叉…...

易点易动固定资产管理系统:实现固定资产与财务系统的高效对接

在企业的日常运营中&#xff0c;固定资产的管理和财务账目的记录是两项不可或缺的任务。然而&#xff0c;由于传统的管理方式存在数据孤岛和信息不一致等问题&#xff0c;往往导致工作效率低下和管理混乱。为了解决这一问题&#xff0c;易点易动固定资产管理系统应运而生。该系…...

做亚马逊多久可以赚钱?做亚马逊需要多少资金?——站斧浏览器

做亚马逊需要时间、资金和全面的市场策略。创业者需要有耐心和决心&#xff0c;同时也要灵活应对市场变化。那么做亚马逊多久可以赚钱,做亚马逊需要多少资金。 做亚马逊多久可以赚钱 首先&#xff0c;就像任何其他生意一样&#xff0c;做亚马逊需要时间和努力来建立起稳定的客…...

计算机应用基础_错题集_基础知识---网络教育统考工作笔记006

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、基础知识部分错题集总结前言 计算机应用基础统考,错题集总结 一、基础知识部分 基础知识部分 2、微处理器芯片的位数即指______。 A.速度 B.字长 C....

C#面试题3

1.请解释一下C#中的并发编程和线程安全性。 并发编程是指在多线程环境下编写代码以实现并发执行的能力。C#提供了一些机制来支持并发编程&#xff0c;如线程、任务和并行循环等。线程安全性是指在多线程环境下&#xff0c;代码能够正确地处理共享数据并保持一致性。线程安全的代…...

MariaDB(基础信息)

文章目录 一、MariaDB1、基本信息2、存储引擎3、兼容性》MySQL、Postgres、MongoDB 和 Oracle4、直接连接其他数据源5、等等等。。。。。。。。。。。。。。。。。。。。。 二、操作和mysql一样参考文章 --------------------机翻内容仅供参考------------------------- 一、…...

SpringBoot + 通义千问 + 自定义React组件,支持EventStream数据解析!

一、前言 大家好&#xff01;我是sum墨&#xff0c;一个一线的底层码农&#xff0c;平时喜欢研究和思考一些技术相关的问题并整理成文&#xff0c;限于本人水平&#xff0c;如果文章和代码有表述不当之处&#xff0c;还请不吝赐教。 最近ChatGPT非常受欢迎&#xff0c;尤其是…...

Redis中文结果查看方式

背景 当使用redis时我们存储到缓存中可能会包含一些中文,例如下面命令 set test 中国 当执行查看时,发现客户端显示的并不是中文而是乱码,例如下面结果 get test \xe4\xb8\xad\xe5\x9b\xbd 现对【\xe4\xb8\xad\xe5\x9b\xbd】的查看有如下几个方式 方式一:通过客户端直…...

计算机组成原理-磁盘存储器

文章目录 总览外存储器磁盘存储器磁盘的性能指标磁盘地址磁盘的工作过程磁盘阵列 总结 总览 外存储器 磁盘存储器 写是利用电流产生磁场从而写磁盘 读是利用载磁体移动时产生的电场从而得到数据 磁性材质易受外界磁场干扰 下图中 载磁体上N S的前后顺序代表对应存储二进制的比…...

(十)学生端搭建

本次旨在将之前的已完成的部分功能进行拼装到学生端&#xff0c;同时完善学生端的构建。本次工作主要包括&#xff1a; 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频

使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

sqlserver 根据指定字符 解析拼接字符串

DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...

现代密码学 | 椭圆曲线密码学—附py代码

Elliptic Curve Cryptography 椭圆曲线密码学&#xff08;ECC&#xff09;是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础&#xff0c;例如椭圆曲线数字签…...

在WSL2的Ubuntu镜像中安装Docker

Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包&#xff1a; for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...

全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比

目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec&#xff1f; IPsec VPN 5.1 IPsec传输模式&#xff08;Transport Mode&#xff09; 5.2 IPsec隧道模式&#xff08;Tunne…...

什么是VR全景技术

VR全景技术&#xff0c;全称为虚拟现实全景技术&#xff0c;是通过计算机图像模拟生成三维空间中的虚拟世界&#xff0c;使用户能够在该虚拟世界中进行全方位、无死角的观察和交互的技术。VR全景技术模拟人在真实空间中的视觉体验&#xff0c;结合图文、3D、音视频等多媒体元素…...

jdbc查询mysql数据库时,出现id顺序错误的情况

我在repository中的查询语句如下所示&#xff0c;即传入一个List<intager>的数据&#xff0c;返回这些id的问题列表。但是由于数据库查询时ID列表的顺序与预期不一致&#xff0c;会导致返回的id是从小到大排列的&#xff0c;但我不希望这样。 Query("SELECT NEW com…...

2.3 物理层设备

在这个视频中&#xff0c;我们要学习工作在物理层的两种网络设备&#xff0c;分别是中继器和集线器。首先来看中继器。在计算机网络中两个节点之间&#xff0c;需要通过物理传输媒体或者说物理传输介质进行连接。像同轴电缆、双绞线就是典型的传输介质&#xff0c;假设A节点要给…...

何谓AI编程【02】AI编程官网以优雅草星云智控为例建设实践-完善顶部-建立各项子页-调整排版-优雅草卓伊凡

何谓AI编程【02】AI编程官网以优雅草星云智控为例建设实践-完善顶部-建立各项子页-调整排版-优雅草卓伊凡 背景 我们以建设星云智控官网来做AI编程实践&#xff0c;很多人以为AI已经强大到不需要程序员了&#xff0c;其实不是&#xff0c;AI更加需要程序员&#xff0c;普通人…...