旋转UITableView时更新UITableViewCells时出现问题

时间:2010-09-08 18:33:23

标签: iphone uitableview rotation

我在自定义UITableViewCell中有一个UILabel,它可以在旋转设备时调整大小。旋转后需要重新计算此标签中的文本,因为我将其缩小到最小尺寸并在末尾添加一些文本。

E.g。数据模型有:“这是一个需要停止的连续句子。”

在纵向模式下,它变为“这是一个连续发送的......更多”

在横向模式中,它变成“这是一个连续的句子......更多”

来自(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation 我能够访问可见的UITableViewCells并更新描述。

问题似乎是有UITableViewCells被缓存但我无法达到。当我在旋转后滚动UITableView时,旋转后位于可见区域下方的一个或两个单元格在标签中没有正确的文本。所以它们没有通过(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath呈现 - 但它们不是由[tableView visibleCells]返回的(或通过循环遍历通过[tableView子视图]返回的所有视图)。

我试图通过这种方法访问“额外”单元格:

for (int index=max + 1; index < max + 3 && index < [cellTypes count]; index++) {
    NSIndexPath *updatedPath = [NSIndexPath indexPathForRow:index inSection:0];
    UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:updatedPath];
    if (cell == nil) { continue; }
    [self updateCellForRotate:cell forRow:index];
}

(其中max是从visibleCells返回的最大行)但是cell始终为nil。

是否有冲洗UITableViewCells的缓存以便它们不被重用?或者访问它们以便我可以更新它们?

谢谢!

5 个答案:

答案 0 :(得分:15)

两件事。 第一。在didRotateFromInterfaceOrientation方法中,您只需重新加载可见行,如下所示:

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation) fromInterfaceOrientation
{
    [super didRotateFromInterfaceOrientation:fromInterfaceOrientation];

    NSLog(@"didRotateFromInterfaceOrientation:%d",fromInterfaceOrientation);
    [tableView reloadRowsAtIndexPaths:[tableView indexPathsForVisibleRows] withRowAnimation:UITableViewRowAnimationNone];
}

然后我建议您将interfaceOrientation数字或简单的表格宽度添加到出列单元格名称,tableView知道一次旋转中的单元格与另一次旋转中的单元格不同。像这样:

- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath withType:(NSString *)s_type
{
    UITableViewCell *cell = nil;
    // add width of table to the name so that rotations will change the cell dequeue names
    s_cell = [s_cell stringByAppendingString:[NSString stringWithFormat:@"%@%d",@"Width",(int)tv.bounds.size.width]];

    NSLog(@"%@",s_cell);
    cell = [tv dequeueReusableCellWithIdentifier:s_cell];
    if( cell == nil ) { 
        cell = [[[UITableViewCell alloc];
        initWithFrame:CGRectZero reuseIdentifier:s_cell] autorelease];
    }
}

答案 1 :(得分:1)

首先,要重新加载所有表格单元格,请使用[self.tableView reloadData]

其次,在(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath方法中添加负责收缩的代码行。

示例:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    //Some identifier and recycling stuff

    if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation)) {
        //Make labels smaller
    }
    else {
        //Make them bigger
    }
}

或者您可以在制作时调用updateCellForRotate:forRow:方法。但我不确定这个功能是如何工作的,所以我不能太具体。

答案 2 :(得分:0)

cellForRowAtIndexPath:中创建单元格时,将其添加到数组中。然后,遍历数组,根据需要更新文本。

希望这有帮助,
jrtc27

编辑:

您说它们是自定义单元格 - 您是否可以更新UITableViewCell子类中的文本?

答案 3 :(得分:-1)

您可以在 shouldAutorotateToInterfaceOrientation 方法上使用此简单的行:

self.view.autoresizesSubviews = YES;

对我来说,它总能成功

答案 4 :(得分:-1)

所以,我最近有一个(我认为是)一个非常类似的问题,并且所有发布的答案都没有帮助我,我很遗憾地说。

我的问题是我故意在旋转时重新调整UITableView的大小并重新定位,我以编程方式完成了。纵向中的表格单元占据了视图的宽度,而在横向中,表格单元格略高但不太宽。然后我根据我们的方向重新定位单元格的元素。

应用程序启动后,第一次查看表就可以了。然后我旋转,发现我似乎有两个元素的实例,这些似乎是第一个表中可见细胞的位置。向后旋转然后使用上一个表格中的元素破坏了初始方向表。

我尝试了上面所有适用的答案,直到我仔细查看了cellForRowAtIndexPath代码:

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

我理解细胞再利用是一个好主意,但我真的不需要保留(如保存)任何细胞,并希望它们在每次旋转后都是明亮的,新的和新的。

编辑:在我自己的应用程序中,我最多可能有20-30行,因为我个人不喜欢长桌。如果为特定查询返回了大量行,我会为用户提供一些过滤器,以帮助他们理清他们想要的行。如果您要显示大量行,那么将它们出列可能会导致您不想要的性能影响。

我所做的只是注释掉if和以下括号,我的表格单元格完全按照我的要求更新:

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

为华夫饼道歉,以及对旧问题的迟到答案。

Ben。

华夫饼干,奶油或糖浆。