2010-05-18 66 views
1

考虑一个非常简单的UITableView具有两种状态之一。UITableView:并列行,页眉和页脚插入/删除

第一状态:

  • 一(整体)表页脚
  • 一个部分包含两排,一节头,和一个段尾

第二状态:

  • 没有表格脚注
  • One section containsi纳克四行和无节页眉/页脚

在两种情况下,每行是本质上的四个可能的UITableViewCell对象中的一个,每个都包含其自己的的UITextField。我们甚至不打算重用或缓存,因为在这种情况下我们只处理四个已知的单元。他们已经在一个附带的XIB中创建,所以我们已经将它们全部连接起来并准备就绪。

现在考虑我们想要在两种状态之间切换。

听起来很容易。假设我们的视图控制器的右栏按钮项目提供了切换支持。我们还会使用ivar和枚举来跟踪当前状态。 (假设我们也处理棒按钮项的标题)。简而言之,我们想清除我们的表的页脚视图,然后插入第三和第四行。我们这种成批更新区块内,像这样:

// Brute forced references to the third and fourth rows in section 0 
NSUInteger row02[] = {0, 2}; 
NSUInteger row03[] = {0, 3}; 

[self.tableView beginUpdates]; 
state = tableStateTwo; // 'internal' iVar, not a property 
self.tableView.tableFooterView = nil; 
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObjects: 
    [NSIndexPath indexPathWithIndexes:row02 length:2], 
    [NSIndexPath indexPathWithIndexes:row03 length:2], nil] 
    withRowAnimation:UITableViewRowAnimationFade]; 
[self.tableView endUpdates]; 

在倒,我们要重新分配表页脚视图(其中,像细胞,是在厦门国际银行准备和等待),并删除最后两个行:

// Use row02 and row03 from earlier snippet 

[self.tableView beginUpdates]; 
state = tableStateOne; 
self.tableView.tableFooterView = theTableFooterView; 
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObjects: 
    [NSIndexPath indexPathWithIndexes:row02 length:2], 
    [NSIndexPath indexPathWithIndexes:row03 length:2], nil] 
    withRowAnimation:UITableViewRowAnimationFade]; 
[self.tableView endUpdates]; 

现在,当表格询问行时,它非常切割和干燥。前两个单元在两种情况下都是相同的。根据状态只有最后两个出现/消失。当Table View要求某个部分中的行数,部分中的页眉/页脚的高度或部分中的页眉/页脚的视图时,请查阅状态ivar。

这最后一点也是我遇到麻烦的地方。

使用上述逻辑,第0部分的页眉/页脚不会消失。具体来说,页脚停留在插入行的下方,但标题现在覆盖最上面一行。如果我们切换回状态,则会移除章节页脚,但章节标题保留。

那么如何使用[self.tableView reloadData]呢?当然,为什么不呢。根据Apple的建议,我们注意不要在更新版块中使用它,只需在endUpdates之后添加即可。

这次,好消息!部分0页眉/页脚消失。 :)

但是...

切换回状态导致一个最精美的混乱!部分0标题返回,仅用于重叠第一行(而不是出现在其上方)。部分0页脚放置在最后一行的下方,但整个表格页脚 - 现在恢复 - 覆盖页脚部分。 Waaaaaah ...现在什么?

可以肯定的是,让我们再次回到状态2。是的,看起来很好。回到国家吗? Yecccch。

我也尝试在其他一些特技中喷洒,例如使用reloadSections:withRowAnimation:,但这只会让事情变得更糟。

NSRange range = {0, 1}; 
NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:range]; 

... 

[self.tableView reloadSections:indexSet withRowAnimation:UITableViewRowAnimationFade]; 

个例子:如果我们调用reloadSections...刚刚更新块结束之前,更改为国家二级皮前两行从视图中,即使空间,他们原本占据遗体。切换回状态返回0的页眉/页脚正常,但前两行保持不可见状态。第二种情况:将reloadSections...移动到更新块之后但在reloadData之前导致全部行变为不可见! (我指的是行作为无形之中,因为,在跟踪,tableView:cellForRowAtIndexPath:返回善意,善意小区对象为那些行。)

案例三:tableView:cellForRowAtIndexPath:后移动reloadSections...给我们带来了一个有点接近,但部分0当切换回状态时,页眉/页脚永远不会返回。

嗯。也许是同时使用reloadSections...reloadData,依据是什么,我在走线时,这使我们看到失礼:

案例四:用reloadSections...彻底更换reloadData。状态2中的所有细胞消失。状态1中的所有细胞仍然缺失(尽管空间保持不变)。

对于那个理论来说非常重要。 :)

通过代码,单元格和视图对象以及剖面高度的追踪都是他们应该在适当的时机。他们只是没有渲染健康。 (更新:视图高度是不一样的,但我没有改变它们!查看我发布的答案更多信息。)

那么,如何破解这种情况?线索欢迎/赞赏!

回答

0

我把这个放在答案部分,因为它有助于(部分?)解释我所看到的。它只是不解释为什么呢。 :)

当我第一次分配一个视图表节头(响应tableView:viewForHeaderInSection:)它的设置,就像我在厦门国际银行定义它:

<UIView: 0x376620; frame = (0 0; 320 50); autoresize = RM+BM; 
layer = <CALayer: 0x376720>> 

一段时间后,我们改变周围的细胞和开始回应tableView:viewForHeaderInSection:,第0部分为零,表示观点获得一些CABasicAnimation爱(表格即将动画,毕竟)......视图框架和自动调整参数改变!

<UIView: 0x376620; frame = (0 0; 320 10); autoresize = W; 
animations = { position=<CABasicAnimation: 0x360b30>; 
bounds=<CABasicAnimation: 0x360a30>; }; layer = <CALayer: 0x376720>> 

如果我们再切换回第一状态,并再次返回同样的观点为分节标题,我们可以看到在分配时有点碎片:

<UIView: 0x376620; frame = (0 0; 320 10); autoresize = W; 
layer = <CALayer: 0x376720>> 

没错。框架和自动大小不会重置!

因此,当从表格的节标题中有效移除视图时,我们似乎遇到了无意的副作用。

我的膝盖反应:“如果你要惹我的UIView,请把它们放回原来的位置!”在这一点上,我不知道这是否是一个现实的期望,但它是第一个想到的。

为了缓解,我想我必须重新设置帧并自动调整每次。嗯...似乎有点混乱,你觉得?也许有更好的方法,或者我在别处犯了一个失礼。

然后再次,这个帧/自动调整大小调整对于整个表格页眉/页脚视图来说似乎没有问题,即使它们被移除并稍后重新添加。只是部分页眉/页脚视图。 (等待,修正:我不能告诉,如果它影响表页脚视图,因为没有东西在它下面有碰撞。)

现在,我已经嵌入每个页眉/页脚视图中的另一个视图。此视图在形式上与父视图相同,但在动画时不会更改。然后,它只是一个调用这个东西类似的影响状态的改变每个页眉/页脚视图的事情:

- (void)fixViewAnimationCruft:(UIView *)theView { 
    UIView *subview = [[theView subviews] objectAtIndex:0]; 
    theView.frame = subview.frame; 
    theView.autoresizingMask = subview.autoresizingMask; 
} 

(不是最原始的方法名称,但它现在做的。)

1

今天我有同样的问题。

过了一段时间,我想出了一个想法,即一切都被画出来的错误。在表视图细胞的方法的出现,我删除这样的条件子句中,一切工作:

//if (cell == nil) { 
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];  
    //} 

我必须在这个问题仔细看看作为代码不再被现在的优化。但它暂时有效。