使用 Instagram 等“更多”按钮在 UITableView 中展开 UILabel
Posted
技术标签:
【中文标题】使用 Instagram 等“更多”按钮在 UITableView 中展开 UILabel【英文标题】:Expand UILabel inside UITableView with "more" button like Instagram 【发布时间】:2017-03-29 14:20:33 【问题描述】:我有一个项目(由其他人编写),其中有一个在表格视图中显示内容和文本的提要。每篇文章对应表格视图中的一个部分,每个部分都有自己的行,对应于内容、文本、按钮等元素。
我需要在表格视图单元格内显示带有“更多”按钮的帖子标题的短标签,当点击更多按钮时,标签将扩展到标题适合的任何大小,所有这些都发生在表格视图单元格内。当点击更多按钮时,我将标签的numberOfLines
属性更改为零,并且由于单元格具有自动高度,我只需要重新加载该特定标题单元格。 (如果我在显示单元格之前首先将 numberOfLines
设置为 0,则单元格会以展开后的大小正确显示。)
我试过了:
[tableView beginUpdates];
tableView endUpdates];
我尝试了各种动画选项:
[tableView reloadRowsAtIndexPaths:@[myPath] withRowAnimation:UITableViewRowAnimation(Bottom,Top,None etc)];
我试过了:
[tableView reloadSections:[NSIndexSet indexSetWithIndex:myPath.section] withRowAnimation:UITableViewRowAnimation(Top,Bottom,None etc)];
但它们都产生相同的结果:整个表格视图布局变得混乱:它跳转到另一个单元格,一些视图变为空白,单元格相互重叠,单元格内的视频停止播放,并且标签没有展开(但会在内部刷新,例如,带有一行的简短预览 txt 会从顶部/底部等动画,但不会展开)。
什么可能导致整个表格视图混乱,以及如何正确地重新加载一个单元格和展开动画,而不会弄乱整个布局?我已经看到了很多关于此的问题和答案,但他们都推荐了我已经尝试过并在上面解释过的选项。
我的应用面向 ios 8.0+
更新:以下是相关代码(删除了一些与布局无关的内部工作部分):
MyCell *cell = (MyCell *)[tableView dequeueReusableCellWithIdentifier: MyCellIdentifier forIndexPath:indexPath];
cell.delegate = self;
cell.indexPathToReloadOnAnimation = indexPath;
cell.shouldShortenCaption = YES;
id post = self.posts[indexPath.section] ;
[cell setPost:post];
return cell;
在setPost:
里面:
if(self.shouldShortenCaption)
captionLabel.numberOfLines = 2;
else
captionLabel.numberOfLines = 0;
NSString *text = [some calculated (deterministic) text from post object];
按钮操作很简单:
self.shouldShortenCaption = NO;
[one of the reload codes that I've written above in the question]
更新 2:以下是有关此问题的更多方法:
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
if (section < self.posts.count)
return 59;
else
return 0;
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
if (section < self.posts.count)
MyFeedHeader *header = [tableView dequeueReusableCellWithIdentifier:MyFeedHeaderIdentifier];
header.delegate = self;
[header setPostIndex:section];
[header setPost:self.posts[section]] ;
return header;
else
return nil;
Header 的setPost:
方法基本上是将相关文本设置为标签(与标题无关,它们是完全不同的单元格。有问题的单元格不是标题单元格)。该表没有任何页脚方法。关于高度的唯一方法是上面的方法。
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
if (section >= self.posts.count)
return 1;
id post = self.posts[section];
[calculate number of rows, which is deterministic]
return [number of rows];
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
BOOL hasCursor = self.cursor && self.hasMore ? 1 : 0;
return self.posts.count + hasCursor;
(post count 和 cursor 和 hasMore 也是确定性的)。
更新 3: 我问了一个问题(虽然有类似的问题,但不是重复的)并得到了一个有用的答案来解决我的问题。投反对票的人能否详细说明他们投反对票的原因?
【问题讨论】:
我们能看到 cellForRow... 和按钮操作代码吗? 另外,UITableViewDataSource
和 UITableViewDelegat
中的任何方法都可能会有所帮助。
@danh 我已经添加了
@Losiowaty 我已经添加了 cellForRow 代码。对于代表,您到底想要什么方法?代码非常复杂,单个文件中有 1000 多行(正如我所说,这不是我编写的代码),在此处发布整个文件既不切实际又非法。如果您问我需要哪一种,我可以添加相关方法。
好吧,我在考虑viewForHeader/FooterInSection:
,如果你有的话。由于您有自动高度,因此很可能没有 heightForRowAtIndexPath
;) 也许 numberOfSection
和 numberOfRows
,如果那里发生了一些不平凡的事情。
【参考方案1】:
这里是一个例子:https://github.com/DonMag/DynamicCellHeight
表 B 是实现“更多/更少”的一种方式(表 A 用于我玩过的另一种布局)。它使用[tableView beginUpdates]; tableView endUpdates];
触发表格重新布局的方法。
关键是正确设置所有约束,因此自动布局引擎可以满足您的期望。
这个例子是用 Swift 编写的,但应该很容易翻译回 Obj-C(我想我是先在 Obj-C 中完成的)。
编辑:一些附加说明...
这是使用动态高度表视图单元格的非常标准的方法。元素之间的垂直间距约束有效地“推出”了单元格的边界。点击此处可在 2 和 0 之间切换标签的 numberOfLines
属性(零表示必要的行数)。在表格视图上连续调用beginUpdates
/ endUpdates
会告诉自动布局引擎重新计算行高而无需重新加载数据。
对于这个例子,我确实使用了一些“技巧”来获得平滑的展开/折叠效果...您在此处看到的多行标签包含在 UIView
中(clipsToBounds
为真)。还有一个控制高度的第二个重复的多行标签(alpha 0,因此不可见)。我发现将可见标签上的 numberOfLines
更改为“捕捉”到 2 行,然后发生大小更改动画......导致文本“跳来跳去”。
为了比较,我将“不太好”的版本添加到我的 GitHub 存储库中。
【讨论】:
虽然我不希望 github 链接在可预见的将来失效,但您能否详细说明“正确设置所有约束”? @Losiowaty 单元格高度必须由内而外完全由其内容的约束来确定。 @Losiowaty - 是的,很难决定要包括多少解释......有很多教程/演练在那里解释动态单元格高度。这只是建立在这样做的“标准”方式之上。但我会更详细地编辑我的答案。 我认为自动布局没有问题,因为表格视图已经设置为自动单元格高度,并且单元格在每种情况下都有正确的高度。但是,当我尝试从一种状态动画到另一种状态时,麻烦就开始了。 @CanPoyrazoğlu 然后看看你的代码,看看 DonMag 的代码。不管有什么不同,这就是你做错了。以上是关于使用 Instagram 等“更多”按钮在 UITableView 中展开 UILabel的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 selenium (Python) 定位 Instagram 关注按钮
Instagram 克隆。单击按钮时,为啥我不能回到上一个片段?