将scrollOffset保存到didEndDisplayingCell中的UITableView数据源,而不是正确地出列

时间:2015-10-20 21:25:40

标签: ios objective-c uitableview

我有一个定义了自定义单元格的UITableView,并且在每个自定义单元格中都有一个UICollectionView。我从顶级数据对象数组中填充数据,每个数据对象都包含集合视图的内部数据对象数组。在JSON中,这看起来像:

[
    {
        "collectionViewData": [
            {
                "name": "subobject1"
            },
            {
                "name": "subobject2"
            },
            {
                "name": "subobject3"
            }
        ],
        "name": "object1"
    },
    {
        "collectionViewData": [
            {
                "name": "subobject1"
            },
            {
                "name": "subobject2"
            }
        ],
        "name": "object2"
    },
    {
        "collectionViewData": [
            {
                "name": "subobject1"
            },
            {
                "name": "subobject2"
            },
            {
                "name": "subobject3"
            },
            {
                "name": "subobject4"
            }
        ],
        "name": "object3"
    }
]

这样可以正常工作,并且按预期运行。我现在要做的是将contentOffset didEndDisplayingCell保存到我的数据源中,以便下次重绘tableview单元格时,滚动位置将被恢复。

这似乎工作得很好 - 除了在出列机制中出现问题,因为每个其他单元格都在加载先前出列的单元格的偏移量 - 例如:

  • 0 = {170,0}的偏移
  • 1 = {0,0}
  • 的偏移量 然后
  • 2加载0' s 偏移量{170,0}

出了什么问题?为什么我会看到此行为以及如何解决此问题?

- (MyTableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellIdentifier = @"Identifier";

    MyTableViewCell *row = (MyTableViewCell *) [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

    if (row == nil)
    {
        row = [[MyTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
    }

    NSInteger idx = (indexPath.row % [MUTABLE_DATASOURCE_ARRAY count]);
    MyCustomCollectionObjectContainer *collectionViewObjectContainer = [MUTABLE_DATASOURCE_ARRAY objectAtIndex:idx];

    [row.collectionView setContentOffset:collectionViewObjectContainer.lastContentOffset animated:NO];
    DDLogDebug(@"ROW %ld %@: cellForRow actual: %@, want: %@", idx, collectionViewObjectContainer.collectionName, NSStringFromCGPoint(row.collectionView.contentOffset), NSStringFromCGPoint(collectionViewObjectContainer.lastContentOffset));
    row.collectionName = collectionViewObjectContainer.collectionName;
    row.collectionViewObjectContainer = collectionViewObjectContainer.innerDataArray;
    row.labelcollectionViewObjectContainer.text = [collectionViewObjectContainer.collectionName uppercaseString];
    [row.labelcollectionViewObjectContainer setNeedsDisplay];

    return row;
}

- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(MyTableViewCell *)row forRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSInteger idx = (indexPath.row % [MUTABLE_DATASOURCE_ARRAY count]);
    MyCustomCollectionObjectContainer *collectionViewObjectContainer = [MUTABLE_DATASOURCE_ARRAY objectAtIndex:idx];
    collectionViewObjectContainer.lastContentOffset = row.collectionView.contentOffset;
    MUTABLE_DATASOURCE_ARRAY[idx] = collectionViewObjectContainer;
    DDLogDebug(@"ROW %ld %@: didEndDisplayingCell set: %@", idx, collectionViewObjectContainer.collectionName, NSStringFromCGPoint(collectionViewObjectContainer.lastContentOffset));
}

更新:在此日志输出中,有时候"实际"是错的,"想要"是正确的,即使在前一行中,我也明确设置了内容偏移量。是否有一种快速而肮脏的方法来强制内容偏移?

[row.collectionView setContentOffset:collectionViewObjectContainer.lastContentOffset animated:NO];
DDLogDebug(@"ROW %ld %@: cellForRow actual: %@, want: %@", idx, collectionViewObjectContainer.collectionName, NSStringFromCGPoint(row.collectionView.contentOffset), NSStringFromCGPoint(collectionViewObjectContainer.lastContentOffset));

除此之外,我忘了(打耳光!)它首先没有工作,所以我在我的集​​合视图子类中覆盖了setContentOffset

- (void)setContentOffset:(CGPoint)contentOffset animated:(BOOL)animated
{

}

卫生署!那没有做任何事情。但是,如果我删除它,现在我已经困扰了我的原始问题,因为当新表视图单元格被初始化时,内部集合视图不会滚动到所需的内容偏移量,即使日志记录正确地注销了内容偏移量每一次现在。也许我需要完全调用setContentOffset之外的其他内容?

1 个答案:

答案 0 :(得分:1)

超级搞砸了,但是当我在拨打setContentOffset之前延迟0.1秒时似乎工作得很好:

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    [row.collectionView setContentOffset: collectionViewObjectContainer.lastContentOffset animated:NO];
});

这似乎更像是一个黑客而不是一个解决方案,但它确实在起作用。

<强>更新

悲惨的结局可能是一个很难解决的问题。事实证明我正在将UITableViewCell子类awakeFromNib中的内容偏移设置为CGPointZero。将其设置为我保存的内容偏移量固定它。