使用像Instagram这样的"更多"按钮展开UITableView中的UILabel

Can*_*ğlu 5 objective-c uitableview ios uitableviewautomaticdimension

我有一个项目(由其他人编写),其中有一个内容和文本显示在表视图中的提要.每个帖子对应于表格视图中的一个部分,每个部分都有自己的行,对应于内容,文本,按钮等元素.

我需要在表格视图单元格中使用"更多"按钮显示帖子标题的短标签,当点击更多按钮时,标签将扩展到标题适合的任何大小,所有这些都发生在表格视图单元格内.当点击更多按钮时,我将标签的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;
Run Code Online (Sandbox Code Playgroud)

内部setPost::

if(self.shouldShortenCaption){
    captionLabel.numberOfLines = 2;
}else{
    captionLabel.numberOfLines = 0;
}
NSString *text = [some calculated (deterministic) text from post object];
Run Code Online (Sandbox Code Playgroud)

按钮动作很简单:

self.shouldShortenCaption = NO;
[one of the reload codes that I've written above in the question]
Run Code Online (Sandbox Code Playgroud)

更新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;
}
Run Code Online (Sandbox Code Playgroud)

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;
}
Run Code Online (Sandbox Code Playgroud)

(发布计数和游标以及hasMore也是确定性的).

更新3:我问了一个问题(虽然有类似的问题,但这并不重复)并得到了一个解决我问题的有用答案.那些贬低者可以详细说明他们被投票的原因吗?

Don*_*Mag 15

这是一个例子:https://github.com/DonMag/DynamicCellHeight

表B是实现"更多/更少"的一种方式(表A是我玩过的另一种布局).它使用[tableView beginUpdates]; tableView endUpdates];触发表重新布局的方法.

关键是正确设置所有约束,因此自动布局引擎可以满足您的期望.

示例是在Swift中,但应该很容易转换回Obj-C(我想我先在Obj-C中完成).

在此输入图像描述

编辑:一些额外的说明......

这是使用非常标准的动态高度表视图单元格方法.元素之间的垂直间距约束有效地"推出"了细胞的边界.这里的点击切换numberOfLines标签的属性在2和0之间(零表示必要的行数).顺序调用beginUpdates/ endUpdates在表视图讲述了自动布局引擎重新计算行高度,而不需要重新加载数据.

对于这个例子,我确实使用了一点"技巧"来获得平滑的展开/折叠效果......你在这里看到的多行标签包含在一个UIView(带有clipsToBoundstrue)中.有一个第二个重复的多线标签(alpha 0,因此它不可见)控制高度.我发现numberOfLines将可见标签上的"快照"更改为2行,然后进行了大小更改动画...导致文本"跳转".

仅仅为了比较,为了比较,我将"不太好"的版本添加到我的GitHub回购中.

在此输入图像描述