xcode Objective C UITableView - 更改单元格高度后表格单元格显示错误的内容

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5080943/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 20:17:24  来源:igfitidea点击:

Objective C UITableView - Table cells display wrong content after changing cell's height

objective-cxcodeuitableviewheightcell

提问by CdB

I'm trying to build an application in xcode, which -beside others- reads an rss feed and displays the posts. I'm new with objective-c and find it a bit hard sometimes.

我正在尝试在 xcode 中构建一个应用程序,它 - 除了其他人 - 读取 rss 提要并显示帖子。我是objective-c的新手,有时觉得有点难。

I use an NSMutableArray for the retrieved stories(posts). Each story is represented by an NSMutableDictionary which contains the title, subject, date and link of the post. All these are displayed in a UITableView within a UIViewController. I have customized my own cell, so i can display multiple labels in them.

我对检索到的故事(帖子)使用 NSMutableArray。每个故事都由一个 NSMutableDictionary 表示,其中包含帖子的标题、主题、日期和链接。所有这些都显示在 UIViewController 中的 UITableView 中。我已经自定义了自己的单元格,因此可以在其中显示多个标签。

My problem is that if i use tableView:heightForRowAtIndexPath:, first 5 cells (that fit to screen) display ok, but if you scroll down, next cells appear to have the same contents with first 5(that is cells 0-4 display ok, cell 5 has contents of cell 0, cell 6 of cell 1 etc)! If i remove the tableView:heightForRowAtIndexPath: everything is just fine (except not having the cell size i want)

我的问题是,如果我使用 tableView:heightForRowAtIndexPath:,前 5 个单元格(适合屏幕)显示正常,但如果向下滚动,下一个单元格似乎与前 5 个单元格具有相同的内容(即单元格 0-4 显示正常) ,单元格 5 具有单元格 0 的内容,单元格 1 的单元格 6 等)!如果我删除 tableView:heightForRowAtIndexPath: 一切都很好(除了没有我想要的单元格大小)

Here's about how the code looks:

以下是代码的外观:

//  NavigationContentsViewController.h
@interface NavigationContentsViewController :
UIViewController <UITableViewDelegate, UITableViewDataSource> {

    UITableView *myTableView;
    IBOutlet UITableView * newsTable;
    UIActivityIndicatorView * activityIndicator;
    CGSize cellSize;
    NSXMLParser * rssParser;
    NSMutableArray * stories; 
    NSMutableDictionary * item; // it parses through the document, from top to bottom...

    NSString * currentElement;
    NSMutableString * currentTitle, * currentDate, * currentSummary, * currentLink;

}

@property(nonatomic,retain)NSMutableArray *itemsList;
@property(nonatomic,retain)UITableView *myTableView;
- (void)parseXMLFileAtURL: (NSString *)URL;

.

.

//NavigationContentsViewController.m
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

// Configure the cell.
static NSString *MyIdentifier = @"MyIdentifier";
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:MyIdentifier];

if (cell == nil){
    cell = [[[CustomCell alloc] initWithFrame:CGRectZero reuseIdentifier:MyIdentifier] autorelease];
    // Set up the cell 
    int storyIndex = indexPath.row;
    //[cell setText:[[stories objectAtIndex: storyIndex] objectForKey: @"title"]];
    //Story title
    //cell.textLabel.text = [[stories objectAtIndex: storyIndex] objectForKey: @"title"];
    //cell.textLabel.font = [UIFont boldSystemFontOfSize:14];
    cell.lTitle.text = [[stories objectAtIndex: storyIndex] objectForKey: @"title"];
    cell.lSummary.text = [[stories objectAtIndex: storyIndex] objectForKey: @"summary"];
    cell.lDate.text = [[stories objectAtIndex: storyIndex] objectForKey: @"date"];

    return cell;
}

return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    NSString *selectedCellItem = [NSString stringWithFormat:@"%d", indexPath.row];

    TableViewController *fvController = [[TableViewController alloc] initWithNibName:@"TableViewController" bundle:[NSBundle mainBundle]];
    fvController.selectedCellItem = selectedCellItem;
    [self.navigationController pushViewController:fvController animated:YES];
    [fvController release];
    fvController = nil; 
}

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    return 80;
}

Any clues? [EDIT: changed int storyIndex = indexPath.row;]

有什么线索吗?[编辑:改变 int storyIndex = indexPath.row;]

回答by Matthias Bauch

This is the usual problem people have with table cell reuse.

这是人们在重用表格单元格时遇到的常见问题。

this line tries to reuse a cell. this means if cell 0 moves off screen it will be reused as cell 5:

这一行试图重用一个单元格。这意味着如果单元格 0 移出屏幕,它将被重用为单元格 5:

CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:MyIdentifier];

if a cell could not be reused you are creating a new one:

如果一个单元格不能被重用,你正在创建一个新的单元格:

if (cell == nil){
    cell = [[[CustomCell alloc] initWithFrame:CGRectZero reuseIdentifier:MyIdentifier] autorelease];

and on the next line is your problem, you set up the cell only if a cell couldn't be reused. Which happens 5 times (for the cells that are visible when the table becomes visible).

下一行是您的问题,只有在单元格无法重复使用时才设置单元格。这发生了 5 次(对于表格可见时可见的单元格)。

But all the cells that your table wants to display afterwards will be reused cells that have already content.

但是您的表格之后想要显示的所有单元格都将是已经有内容的重复使用的单元格。

    // Set up the cell 
    /*...*/


but don't worry. this is very easy to fix. You have to separate the creation of your cell from its configuration. Just shift some code around like this:

不过别担心。这很容易修复。您必须将单元的创建与其配置分开。只需像这样移动一些代码:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *MyIdentifier = @"MyIdentifier";
    CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:MyIdentifier];

    if (cell == nil){
        cell = [[[CustomCell alloc] initWithFrame:CGRectZero reuseIdentifier:MyIdentifier] autorelease];
    }
    // whatever happened before. You have a valid cell at this point.

    // Set up the cell 
    int storyIndex = indexPath.row;
    //[cell setText:[[stories objectAtIndex: storyIndex] objectForKey: @"title"]];
    //Story title
    //cell.textLabel.text = [[stories objectAtIndex: storyIndex] objectForKey: @"title"];
    //cell.textLabel.font = [UIFont boldSystemFontOfSize:14];
    cell.lTitle.text = [[stories objectAtIndex: storyIndex] objectForKey: @"title"];
    cell.lSummary.text = [[stories objectAtIndex: storyIndex] objectForKey: @"summary"];
    cell.lDate.text = [[stories objectAtIndex: storyIndex] objectForKey: @"date"];
    return cell;
}


EDIT: maybe I should read the question next time. But I guess I'm still 100% correct.

编辑:也许我下次应该阅读这个问题。但我想我仍然是 100% 正确的。

If i remove the tableView:heightForRowAtIndexPath: everything is just fine (except not having the cell size i want)

如果我删除 tableView:heightForRowAtIndexPath: 一切都很好(除了没有我想要的单元格大小)

I think this is coincidence. How much cells do you have? I guess around 7 or 8? Everything is fine because all your cells are visible at the same time. So there is no need to reuse a cell, and they all have the content they should have.

我认为这是巧合。你有多少细胞?我猜大约是 7 或 8?一切都很好,因为您的所有单元格同时可见。所以没有必要重复使用一个单元格,它们都拥有应有的内容。

回答by FeifanZ

Using [indexPath indexAtPosition…] is most likely your source of error—it's not getting your proper index path.

使用 [indexPath indexAtPosition...] 很可能是你的错误来源——它没有得到你正确的索引路径。

However, if you are creating a CustomCell (hopefully in IB?) then you should set the size of the cell in IB, and not do it in code.

但是,如果您正在创建一个 CustomCell(希望在 IB 中?),那么您应该在 IB 中设置单元格的大小,而不是在代码中进行设置。