使用 "more" 按钮像 Instagram 一样在 UITableView 中扩展 UILabel
Expand UILabel inside UITableView with "more" button like Instagram
我有一个项目(由其他人编写),其中有一个提要,其内容和文本显示在 table 视图中。每个 post 对应 table 视图中的一个部分,每个部分都有自己的行,对应于内容、文本、按钮等元素。
我需要在 table 视图单元格内使用 "more" 按钮显示 post 字幕的短标签,当点击更多按钮时,标签将扩展到任意大小标题适合,所有发生在 table 视图单元格内。当点击更多按钮时,我将标签的 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)];
但它们都产生相同的结果:整个 table 视图布局变得混乱:它跳转到另一个单元格,一些视图变为空白,单元格相互重叠,单元格内的视频停止播放,并且标签不会展开(但会在自身内部刷新,例如,带有一行的简短预览 txt 从 top/bottom 等动画但不会展开)。
什么可能导致整个 table 视图混乱,我如何才能正确地重新加载一个单元格和展开动画,而不弄乱整个布局?我已经看到很多关于此的问题和答案,但他们都推荐我已经尝试过并在上面解释过的选项。
我的应用程序目标 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:
方法基本上是将相关文字设置为标签(与标题无关,它们是完全不同的单元格。有问题的单元格不是header 细胞)。 table 没有任何页脚方法。关于高度的唯一方法是上面的方法。
- (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: 我问了一个问题(这不是重复的问题,即使有类似的问题)并得到了一个有用的答案,解决了我的问题。投反对票的人能否详细说明他们投反对票的原因?
这是一个例子:https://github.com/DonMag/DynamicCellHeight
Table B 是实现 "More/Less" 的一种方式(Table A 是我玩过的另一种布局)。它使用 [tableView beginUpdates]; tableView endUpdates];
方法触发 table re-layout.
关键是正确设置所有约束,这样 Auto-Layout 引擎就能达到您的预期。
示例在 Swift 中,但应该很容易翻译回 Obj-C(我想我是先在 Obj-C 中做的)。
编辑:一些补充说明...
这是使用 dynamic-height table 查看单元格的非常标准的方法。元素之间的垂直间距约束有效 "pushes out" 单元格的边界。点击此处可在 2 和 0 之间切换标签的 numberOfLines
属性(零表示需要的行数)。在 table 视图上连续调用 beginUpdates
/ endUpdates
告诉 auto-layout 引擎重新计算行高 而无需 重新加载数据.
对于这个例子,我确实使用了一点 "trickery" 来获得平滑的 expand/collapse 效果...您在这里看到的多行标签包含在 UIView
中(带有 clipsToBounds
真)。还有第二个重复的多行标签(alpha 0 所以它不可见)控制高度。我发现将可见标签类型 "snapped" 上的 numberOfLines
更改为 2 行,然后发生了大小更改动画...导致文本 "jumping around."
为了比较,我将 "not so good" 版本添加到我的 GitHub 存储库中。
我有一个项目(由其他人编写),其中有一个提要,其内容和文本显示在 table 视图中。每个 post 对应 table 视图中的一个部分,每个部分都有自己的行,对应于内容、文本、按钮等元素。
我需要在 table 视图单元格内使用 "more" 按钮显示 post 字幕的短标签,当点击更多按钮时,标签将扩展到任意大小标题适合,所有发生在 table 视图单元格内。当点击更多按钮时,我将标签的 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)];
但它们都产生相同的结果:整个 table 视图布局变得混乱:它跳转到另一个单元格,一些视图变为空白,单元格相互重叠,单元格内的视频停止播放,并且标签不会展开(但会在自身内部刷新,例如,带有一行的简短预览 txt 从 top/bottom 等动画但不会展开)。
什么可能导致整个 table 视图混乱,我如何才能正确地重新加载一个单元格和展开动画,而不弄乱整个布局?我已经看到很多关于此的问题和答案,但他们都推荐我已经尝试过并在上面解释过的选项。
我的应用程序目标 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:
方法基本上是将相关文字设置为标签(与标题无关,它们是完全不同的单元格。有问题的单元格不是header 细胞)。 table 没有任何页脚方法。关于高度的唯一方法是上面的方法。
- (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: 我问了一个问题(这不是重复的问题,即使有类似的问题)并得到了一个有用的答案,解决了我的问题。投反对票的人能否详细说明他们投反对票的原因?
这是一个例子:https://github.com/DonMag/DynamicCellHeight
Table B 是实现 "More/Less" 的一种方式(Table A 是我玩过的另一种布局)。它使用 [tableView beginUpdates]; tableView endUpdates];
方法触发 table re-layout.
关键是正确设置所有约束,这样 Auto-Layout 引擎就能达到您的预期。
示例在 Swift 中,但应该很容易翻译回 Obj-C(我想我是先在 Obj-C 中做的)。
编辑:一些补充说明...
这是使用 dynamic-height table 查看单元格的非常标准的方法。元素之间的垂直间距约束有效 "pushes out" 单元格的边界。点击此处可在 2 和 0 之间切换标签的 numberOfLines
属性(零表示需要的行数)。在 table 视图上连续调用 beginUpdates
/ endUpdates
告诉 auto-layout 引擎重新计算行高 而无需 重新加载数据.
对于这个例子,我确实使用了一点 "trickery" 来获得平滑的 expand/collapse 效果...您在这里看到的多行标签包含在 UIView
中(带有 clipsToBounds
真)。还有第二个重复的多行标签(alpha 0 所以它不可见)控制高度。我发现将可见标签类型 "snapped" 上的 numberOfLines
更改为 2 行,然后发生了大小更改动画...导致文本 "jumping around."
为了比较,我将 "not so good" 版本添加到我的 GitHub 存储库中。