UITableView无法正常更新(即使调用reloadData)

时间:2009-08-18 15:37:08

标签: iphone uitableview

我正在制作一个iPhone应用程序,其部分界面与iPhone YouTube应用程序的'最受欢迎'部分完全相同。

此“热门”部分可从底部的标签栏访问,顶部的导航栏包含 UISegmentedControl ,可选择“今天,本周,月等”。

因为大多数应用程序都包含UITableViews,其中单元格包含非常相似的结构化内容,所以我创建了一个公共 MyAppTableViewController ,它继承了 UITableViewController 。因此,我的“热门”部分包含 PopularTableViewController ,它继承了 MyAppTableViewController 。实际的 UITableView 位于 MyAppTableViewController中。

PopularTableViewController 的方法有:

- (void) segmentChangeTimeframe:(id)sender {
    UISegmentedControl *segCtl = sender;
    if( [segCtl selectedSegmentIndex] == 0 )
    {
        // Call [self parse-xml-method-which-resides-in-MyAppTableViewController]
    }
    //... ... ...
}

MyAppTableViewController 使用 NSXMLParser ,因此有代码:

- (void)parserDidEndDocument:(NSXMLParser *)parser {
    [self.myTableView reloadData];
}

(还有其他方法可以更新表视图从中获取数据的数据结构)

我已将控制台输出代码放入xml解析方法中,并且在运行时,选择不同的段会导致正确解析正确的xml文件,并且数据结构似乎包含正确的值。

问题是表格单元格的内容不会改变! GRR!除非!...一个单元格被滚动出视图,然后返回视图......然后它被改变了!

我已经做了很多关于这个问题的搜索,并且针对类似问题的一个建议是将[self.myTableView reloadData]放入其自己的方法中,例如: myReloadDataMethod 然后使用:

[self performSelectorOnMainThread:@selector(myReloadDataMethod) withObject:nil waitUntilDone:NO];

我尝试将上面的代码放入parserDidEndDocument方法,它完全没有区别!我非常难过,我想知道是否有人知道这里发生了什么。

更新

填充单元格的代码完成:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *MyIdentifier = @"MyIdentifier";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:MyIdentifier] autorelease];
    }

    // Set up the cell
    int itemIndex = [indexPath indexAtPosition: [indexPath length] - 1];
    NSString *artistName = [[myItemList objectAtIndex: itemIndex] objectForKey: @"itemA"];
    NSString *mixName = [[myItemList objectAtIndex: itemIndex] objectForKey: @"itemB"];
    cell.textLabel.text = itemA;
    cell.detailTextLabel.text = itemB;
    cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;

    return cell;
}

以上代码位于 MyAppTableViewController 中,这也是myItemList所在的位置。

4 个答案:

答案 0 :(得分:5)

您的-performSelectorOnMainThread:代码适用于在后台线程上更改模型类的时间。 UI事件(包括-reloadData)需要在主线程上发生。如果您没有使用后台线程,那么这是不必要的。如果你是,那就是强制性的。

如果要更改特定单元格的值,则实现此方法的方法是更改​​单元格本身。在iPhone上,单元格是完整视图(与Mac不同),因此如果您想更改其数据,只需更改其数据并调用-setNeedsDisplay即可。您可以使用-cellForRowAtIndexPath:获取给定位置的单元格(视图)。您可以使用-indexPathsForVisibleRows-visibleCells确定给定单元格是否在屏幕上。

很少需要致电-reloadData。只有在丢弃所有内容并加载完全不同的数据时才应该这样做。相反,您应该使用插入/删除例程来添加/删除行,并且只应在数据更改时更新现有行的视图。

答案 1 :(得分:1)

我遇到了同样的问题,这是因为我在没有调用endUpdates的情况下进行了[tableView beginUpdates]调用。

答案 2 :(得分:0)

您是否尝试过[tableView setNeedsDisplay:YES]

答案 3 :(得分:-1)

在调用-reloadData之后,你是否收到了对tableView的回调:numberOfRowsInSection :? 我几乎可以肯定,self.myTableView在这里是零:

    - (void)parserDidEndDocument:(NSXMLParser *)parser {
[self.myTableView reloadData];

}