estimatedHeight方法导致重叠的UITableView节标题和奇数标题动画

时间:2014-12-31 15:08:23

标签: ios uitableview autolayout

我有UITableView个多个部分。我在beginUpdates中使用endUpdates / tableView:didSelectRowAtIndexPath:并检测tableView:heightForRowAtIndexPath:中的所选行,以设置所选单元格的高度变化动画。这很好用,但因为我使用DynamicType这样的东西,高度计算可能很耗时,所以我实现了很棒的tableView:estimatedHeightForRowAtIndexPath:tableView:estimatedHeightForHeaderInSection:来提供一个大致恒定的值来加速这个过程。

问题在于,当我对行或节标题使用estimatedHeight方法时,节标题会奇怪地生成动画。标题将下降~50像素,然后在单元格的内容上进行动画处理。有时,标题会在单元格的中间重复,永远不会消失。删除两种 estimatedHeight方法,一切都很好。如果存在estimatedHeight方法,即使它们返回与heightFor方法相同的值,也会发生奇怪的动画。

可靠地再现此错误的简单代码如下所示,完整的示例项目目前在此public Dropbox link处可用。有没有办法保持estimatedHeight方法大大减少高度计算时间,同时防止这些标题异常? Xcode 6.1.1,iOS 8.1.2。

#import "ViewController.h"

const CGFloat HEADER_HEIGHT = 24;
const CGFloat EXPANDED_HEIGHT = 150;
const CGFloat COLLAPSED_HEIGHT = 70;
NSString * const REUSE_IDENTIFIER = @"BasicCellReuseIdentifier";

@implementation ViewController

/*
 * Cell appearance.
 */

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:REUSE_IDENTIFIER forIndexPath:indexPath];
    cell.textLabel.text = [NSString stringWithFormat:@"Section %ld, Row %ld", (long)indexPath.section, (long)indexPath.row];
    return (cell);
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
    return ([NSString stringWithFormat:@"Section %ld", (long)section]);
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return (2);
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return (2000);
}

/*
 * Heights.
 */

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    return (HEADER_HEIGHT);
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if ([[tableView indexPathForSelectedRow] isEqual:indexPath])
        return (EXPANDED_HEIGHT);
    return (COLLAPSED_HEIGHT);
}

/*
 * Actions.
 */

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    /* Animate cell height changes */
    [tableView beginUpdates];
    [tableView endUpdates];
}

/******************************************************************************
 ******** FIXME: Disable estimatedHeight methods and things work fine. ********
 *****************************************************************************/

- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForHeaderInSection:(NSInteger)section
{
    return (HEADER_HEIGHT);
}

- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if ([[tableView indexPathForSelectedRow] isEqual:indexPath])
        return (EXPANDED_HEIGHT);
    return (COLLAPSED_HEIGHT);
}

@end

Overlapping section header

1 个答案:

答案 0 :(得分:-1)

我不认为这是最好的解决方案,但它比循环更好: 你可以保留一个数组来告诉每个索引是否扩展。本质上,索引1将是数组中的插槽1,它将具有一个真值,以显示它已展开。

如果这些单元格是从本地对象派生的,则可以添加扩展属性。