我有一个定义了自定义单元格的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单元格时,滚动位置将被恢复。
这似乎工作得很好 - 除了在出列机制中出现问题,因为每个其他单元格都在加载先前出列的单元格的偏移量 - 例如:
出了什么问题?为什么我会看到此行为以及如何解决此问题?
- (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
之外的其他内容?
答案 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。将其设置为我保存的内容偏移量固定它。