3

这是我想要的应用程序。下图是两个 iPhone 应用商店的截图:

截图 1

截图 2

我基本上需要一个“阅读更多”功能,就像它在应用商店中使用的一样(参见上面两张图片中的“描述”部分)。我假设这里的每个部分(描述新增功能信息等)都是一个表格视图单元格。而里面的文字是一个UILabel或者UITextField。

这是我迄今为止尝试添加此功能的方法:

NSString *initialText = @"Something which is not a complete text and created just as an example to...";

NSString *finalText = @"Something which is not a complete text and created just as an example to illustrate my problem here with tableviews and cel heights. bla bla bla";

NSInteger isReadMoreTapped = 0;

我的 cellForRowAtIndexPath 函数:

// Other cell initialisations 
if(isReadMoreTapped==0)
    cell.label.text =  initialText;
else
    cell.label.text = finalText;

return cell;

我的 heightForRowAtIndexPath 函数:

// Other cell heights determined dynamically
if(isReadMoreTapped==0){
    cell.label.text =  initialText;
    cellHeight =  //Some cell height x which is determined dynamically based on the font, width etc. of the label text
}
else{
    cell.label.text = finalText;
    cellHeight = //Some height greater than x determined dynamically
}
return cellHeight;

最后,我的 IBAction readMoreTapped方法在点击更多按钮时被调用:

isReadMoreTapped = 1;

[self.tableView beginUpdates];

[self.tableView endUpdates];

NSIndexPath* rowToReload = [NSIndexPath indexPathForRow:2 inSection:0]; // I need to reload only the third row, so not reloading the entire table but only the required one
NSArray* rowsToReload = [NSArray arrayWithObjects:rowToReload, nil];
[self.tableView reloadRowsAtIndexPaths:rowsToReload withRowAnimation:UITableViewRowAnimationNone];

完成所有这些之后,我确实获得了所需的功能。计算该特定单元格的新高度并将新文本加载到其中。但是TableView 上有一个非常不自然的混蛋,这会导致糟糕的用户体验。不过,应用商店的“更多”按钮并非如此。在它的情况下没有不自然的混蛋。TableView 保持原位,只有更改的单元格的大小随着文本的平滑显示而增加。

如何实现 iPhone 应用商店“更多”按钮中的流畅度?

4

4 回答 4

4

您的问题可能来自重新加载行。您想尝试直接配置单元格属性。我通常使用专用方法来配置我的单元格内容,因此我不必重新加载行。

- (void)configureCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    if(isReadMoreTapped==0)
        cell.label.text =  initialText;
    else
        cell.label.text = finalText;
    // all other cell configuration goes here
}

此方法从 cellForRowAtIndexPath 方法调用,它将配置单元格

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    [self configureCell:cell forRowAtIndexPath:indexPath];
    return cell;
}

你可以直接调用这个方法来避免重新加载:

isReadMoreTapped = 1;

[self.tableView beginUpdates];

[self.tableView endUpdates];

NSIndexPath* rowToReload = [NSIndexPath indexPathForRow:2 inSection:0];
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:rowToReload];
[self configureCell:cell forRowAtIndexPath:rowToReload];
于 2013-07-09T06:38:19.967 回答
1

请尝试对您的代码进行以下更改,我认为它会解决您的问题。

  1. 无需设置cell.label.textheightForRowAtIndexPath请删除它们。

  2. readMoreTapped,更新表就足够了:

    isReadMoreTapped = 1;

    [self.tableView 开始更新];

    [self.tableView endUpdates];

于 2013-07-09T07:34:44.150 回答
0

删除对以下内容的调用:

[self.tableView beginUpdates];
[self.tableView endUpdates];

或更改以确保您的重新加载代码在它们之间。我会删除它们,因为您使用的方法可以很好地处理单行重新加载:

[self.tableView reloadRowsAtIndexPaths:rowsToReload withRowAnimation:UITableViewRowAnimationNone];

您只需要指定一个行动画,如淡入淡出。

于 2013-07-09T06:45:45.140 回答
0

好的,我终于在马蒂亚斯的回答(接受的答案)和我自己的优化的帮助下解决了这个问题。绝对应该做的一件事是创建一个专用函数,例如configureCell: forRowAtIndexPath:直接配置单元格属性(请参阅 Mathias 的答案)。一切都与马蒂亚斯的回答一样,除了:

以前,每次调用函数时我都在计算每个单元格的高度,而heightForRowAtIndexPath没有在任何地方缓存(保存)它们,因此再次计算每个单元格的高度。相反,您需要做的是将这些单元格高度保存在一个数组/字典中,以便每当点击更多按钮时,您只计算已更改单元格的高度。对于其他单元格,只需查询数组/字典并返回保存的单元格高度。这应该可以解决单元格高度更新后 tableView 滚动的任何问题。如果还有其他人遇到与此类似的问题,请在此帖子下发表评论。我很乐意提供帮助[self.tableView beginUpdates];[self.tableView endUpdates];

于 2013-07-10T06:14:35.327 回答