使用“more"在 UITableView 中展开 UILabel像 Instagram 一样的按钮 [英] Expand UILabel inside UITableView with "more" button like Instagram

查看:26
本文介绍了使用“more"在 UITableView 中展开 UILabel像 Instagram 一样的按钮的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

我需要在表格视图单元格内显示一个带有更多"按钮的帖子标题的短标签,当点击更多按钮时,标签将扩展到标题适合的任何大小,所有这些都发生在表格视图单元格内.当点击更多按钮时,我将标签的 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] ;[单元格集邮局:邮报];返回单元格;

setPost::

if(self.shouldShortenCaption){captionLabel.numberOfLines = 2;}别的{captionLabel.numberOfLines = 0;}NSString *text = [来自帖子对象的一些计算的(确定性的)文本];

按钮操作很简单:

self.shouldShortenCaption = NO;[我在上面的问题中编写的重新加载代码之一]

更新 2:以下是有关此问题的更多方法:

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {如果(部分< self.posts.count){返回 59;}别的返回0;}- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {如果(部分< self.posts.count){MyFeedHeader *header = [tableView dequeueReusableCellWithIdentifier:MyFeedHeaderIdentifier];header.delegate = self;[header setPostIndex:section];[header setPost:self.posts[section]] ;返回标题;}别的返回零;}

Header 的 setPost: 方法基本上将相关文本设置为标签(与标题无关,它们是完全不同的单元格.有问题的单元格不是标题单元格).该表没有任何页脚方法.关于高度的唯一方法就是上面那个.

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {如果(部分> = self.posts.count){返回 1;}id post = self.posts[section];[计算行数,这是确定性的]返回[行数];}- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {BOOL hasCursor = self.cursor &&self.hasMore ?1:0;返回 self.posts.count + hasCursor;}

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

更新 3: 我问了一个问题(这不是重复的,即使有类似的问题)并得到了一个有用的答案,解决了我的问题.投反对票的人能否详细说明他们投反对票的原因?

解决方案

这里是一个例子:

一些附加说明...

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

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

为了方便起见,我将不太好"的版本添加到我的 GitHub 存储库中以进行比较.

I've got a project (that has been written by other people) where there's a feed with content and text displayed inside a table view. Each post corresponds to one section in table view, and each section has its own rows corresponding to elements like content, text, like button etc.

I need to display a short label for post captions with a "more" button inside table view cell, and when more button is tapped, the label will expand to whatever size the caption fits, all happening inside a table view cell. When the more button is tapped I change the label's numberOfLines property to zero, and as the cells have automatic height, all I need is to reload that particular caption cell. (the cell displays correctly with the expanded size if I set numberOfLines to 0 at the first place before displaying the cell.)

I've tried:

[tableView beginUpdates]; tableView endUpdates];

I've tried various animation options with:

[tableView reloadRowsAtIndexPaths:@[myPath] withRowAnimation:UITableViewRowAnimation(Bottom,Top,None etc)];

I've tried:

[tableView reloadSections:[NSIndexSet indexSetWithIndex:myPath.section] withRowAnimation:UITableViewRowAnimation(Top,Bottom,None etc)];

But they all yield the same result: the whole table view layout gets messed up: it jumps to another cell, some views go blank, cells overlap each other, video inside cells stop playing, and the label doesn't expand (but refreshes inside itself, e.g. that short preview txt with one line animates from top/bottom etc but doesn't expand).

What might be causing the mess up of the whole table view and how I can reload just one cell correctly with and expansion animation, without messing up the whole layout? I've seen many questions and answers regarding this, but they all recommend the options that I've already tried and explained above.

My app targets iOS 8.0+

UPDATE: Here is the relevant code (with some parts regarding inner workings that aren't related to layout, removed):

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;

And inside setPost::

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

Button action is simple:

self.shouldShortenCaption = NO;
[one of the reload codes that I've written above in the question]

UPDATE 2: Here are some more methods regarding the issue:

- (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's setPost: method basically sets the relevant texts to labels (which have nothing to do with the caption, they are completely different cells. the problematic cell is not the header cell). The table doesn't have any footer methods. The only method regarding height is the one above.

- (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 and cursor and hasMore are also deterministic).

UPDATE 3: I've asked a question (which wasn't a duplicate, even though there are similar questions) and got a useful answer that solved my problem. Can the downvoters please elaborate the reason that they've downvoted?

解决方案

Here is an example: https://github.com/DonMag/DynamicCellHeight

Table B is one way of accomplishing "More/Less" (Table A was for another layout I played around with). It uses the [tableView beginUpdates]; tableView endUpdates]; method of triggering the table re-layout.

The key is getting all your constraints set up correctly, so the Auto-Layout engine does what you expect.

The example is in Swift, but should be really easily translated back to Obj-C (I think I did it in Obj-C first).

Edit: some additional notes...

This is using a pretty standard method of dynamic-height table view cells. The vertical spacing constraints between elements effectively "pushes out" the bounds of the cell. The tap here toggles the numberOfLines property of the label between 2 and 0 (zero meaning as many lines as necessary). Sequential calls to beginUpdates / endUpdates on the table view tells the auto-layout engine to recalculate the row heights without needing to reload the data.

For this example, I did use a little "trickery" to get the smooth expand/collapse effect... The multiline label you see here is contained in a UIView (with clipsToBounds true). There is a second, duplicate multiline label (alpha 0 so it's not visible) that is controlling the height. I found that changing the numberOfLines on the visible label sort of "snapped" to 2 lines, and then the size change animation took place... resulting in the text "jumping around."

Just for the heck of it, I added the "not so good" version to my GitHub repo for comparison's sake.

这篇关于使用“more"在 UITableView 中展开 UILabel像 Instagram 一样的按钮的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆