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

发布于 2024-10-18 12:19:06 字数 2978 浏览 2 评论 0原文

我正在尝试在 xcode 中构建一个应用程序,它除了其他应用程序之外还读取 rss 提要并显示帖子。我是 Objective-C 的新手,有时发现它有点困难。

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

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

以下是代码的外观:

//  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;
}

有什么线索吗? [编辑:更改 intstoryIndex = indexPath.row;]

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.

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.

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)

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;]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

世界等同你 2024-10-25 12:19:06

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

该行尝试重用单元格。这意味着如果单元格 0 移出屏幕,它将被重新用作单元格 5:

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

如果单元格无法重复使用,您将创建一个新单元格:

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

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

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

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

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

- (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;
}

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

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

我认为这是巧合。你有多少细胞?我猜大概七八点吧?一切都很好,因为您的所有细胞同时可见。所以不需要重复使用一个cell,它们都有它们应该有的内容。

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:

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).

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.

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

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.

沙与沫 2024-10-25 12:19:06

使用 [indexPath indexAtPosition...] 很可能是错误的根源 - 它没有获得正确的索引路径。

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

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文