UITableView 没有显示正确的单元格 [英] UITableView not showing the right cells

查看:55
本文介绍了UITableView 没有显示正确的单元格的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有 2 个 tableView,第一个是主表,第二个是收藏夹表.

I have 2 tableViews, the first one is the Main table and the second one is the Favorites table.

一切都用 plist 处理.

Everything is handled with a plist.

从右上角的第一个表格的 detailView 中,我创建了一个按钮,将那个单元格的值是或否写入 plist,以便该特定单元格将显示在表格收藏夹中.

From the detailView of the first table, in the upper-right corner, I created a button that writes to the plist the value YES or NO for that cell, so that that specific cell will be shown in the table Favorites.

现在的问题是:

  • 我从第一个表中选择一行,即主表.detailView 出现,我点击 UIBarButton 使该细节成为收藏夹(因此星形图像作为图像出现在按钮中,让用户知道该单元格是收藏夹).好的.
  • 我转到第二个表,收藏夹,选择以前收藏的单元格,我看到星号是空的,然后将 bool 值设置为 NO(并且应该设置为 YES 因为我喜欢它的时刻之前).

我注意到,如果我将 firstTable第一 项添加到收藏夹中,那么第二个视图中的其他单元格会正确显示,即使我将它们全部收藏在第一个视图中.

I noticed that if i add to favorites the first item of the firstTable, then the other cells in the second view are shown correctly, even after i favorited them all in the first view.

有点棘手,我知道,但它正在发生.

A bit tricky, i know, but it's happening.

知道为什么吗?

我用来阅读 plist 的方法如下:

The method i'm using for reading the plist is the following:

- (NSArray*)readPlist 
{  
    NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); 
    NSString *plistPath = [[documentPaths lastObject] stringByAppendingPathComponent:@"tipsList.plist"]; 
    NSFileManager *fMgr = [NSFileManager defaultManager]; 
    if (![fMgr fileExistsAtPath:plistPath]) { 
        plistPath = [[NSBundle mainBundle] pathForResource:@"list" ofType:@"plist"]; 

    } 

    NSMutableArray *returnArr = [NSMutableArray arrayWithContentsOfFile:plistPath]; 
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"isFav == YES"]; 

    for (NSDictionary *sect in returnArr) { 
        NSArray *arr = [sect objectForKey:@"Rows"]; 
        [sect setValue:[arr filteredArrayUsingPredicate:predicate] forKey:@"Rows"]; 
    } 
    return returnArr;
    [self.tableView reloadData];
}

cellForRow:

cellForRow:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{
    static NSString *CellIdentifier = @"Cell";

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


    NSArray *rows;
    if (tableView == self.searchDisplayController.searchResultsTableView) {
        rows = filteredList;
    } else {
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"isFav == YES"]; 

        NSDictionary *section = [localSortedTips objectAtIndex:indexPath.section];
        rows = [section objectForKey:@"Rows"];
        [rows filteredArrayUsingPredicate:predicate];

    }

    cell.textLabel.text = [[rows objectAtIndex:indexPath.row] objectForKey:@"name"];        
    return cell;
}

还有 didSelectRow:

And the didSelectRow:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{   NSDictionary *section = [localList objectAtIndex:indexPath.section];

    NSArray *rows = [section objectForKey:@"Rows"];
    NSDictionary *item = [rows objectAtIndex:indexPath.row];

        detailViewController *detail = [[detailViewController alloc] initWithNibName:@"detailViewController" bundle:nil];
        detail.indexPath = indexPath;
        detail.imageString = [item valueForKey:@"image"]; 
        detail.nameString = [item valueForKey:@"name"];
        detail.title = [item valueForKey:@"name"];
        detail.descriptionString = [item valueForKey:@"description"];

        [self.navigationController pushViewController:detail animated:YES];
        [tableView deselectRowAtIndexPath:indexPath animated:YES];

        [detail release];
    }

}

使用图片编辑

好吧.我选择 mainTable 的 first 部分中的 first 行,然后出现 detailView:

Okay so. I select the first row in the first section of the mainTable, and the detailView appears:

然后我通过那个小星星来收藏它,在 plist 中将它的值设置为 YES

Then i favorite it through that little star, setting its value to YES in the plist

然后我进入收藏夹表,点击以前收藏的元素,它看起来像这样

Then I go into the Favorites table, clicking on the previously favorited element and it appears like so

好的.这有效.但仅限于这个

OK. This works. but only for this one!

事实上,如果我尝试选择 mainTable 中间的一行,并尝试对其进行收藏,detailView 看起来像

In fact, if i try to select i.e. a row in the middle of the mainTable, and try to favoriting it, the detailView looks like

但是,在收藏夹表中选择它看起来像这样,空星,而它应该被收藏然后填充.如果我尝试通过星号收藏它,然后返回到收藏夹表,则主表格中的前一行会出现,即使它没有被收藏.

But then, selecting it in the Favorites table looks like so, empty star, while it should be favorited and then filled. If i try to favorite it through the star, and coming back to the Favorites table, the previous row in the mainTable appears, even if it's not favorited.

我注意到如果我保留第一个元素,它工作正常,但如果我删除它,它就不再起作用了.:\

I noticed that if i keep the first element, it works fine, but if i remove it, it doesn't work ANYTHING anymore. :\

非常感谢任何帮助,从 2 周开始.

Any help highly appreciated,stuck from 2 weeks.

推荐答案

您传递给 favoritesView 中的 detailControllerindexPath 不是和 mainView 中的一样.所以你必须做一些魔术来将过滤后的 indexPath 解析回原始的未过滤列表.

The indexPath you passing to your detailController in favoritesView isn't the same like the one in mainView. So you have to do some magic to parse the filtered indexPath back to the original unfiltered list.

- (NSArray*)readPlist // still filtered list
{  
    NSMutableArray *returnArr = [[self readFullPlist] mutableCopy];
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"isFav == YES"];

    for (NSDictionary *sect in returnArr) {
        NSArray *arr = [sect objectForKey:@"Rows"];
        [sect setValue:[arr filteredArrayUsingPredicate:predicate] forKey:@"Rows"];
    }

    return returnArr;
}

- (NSArray*)readFullPlist // split that method to get the unfiltered list separately
{
    NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); 
    NSString *plistPath = [[documentPaths lastObject] stringByAppendingPathComponent:@"tipsList.plist"]; 
    NSFileManager *fMgr = [NSFileManager defaultManager]; 
    if (![fMgr fileExistsAtPath:plistPath]) { 
        NSString *bundlePlistPath = [[NSBundle mainBundle] pathForResource:@"tipsList" ofType:@"plist"];
        [self writePlist:[NSArray arrayWithContentsOfFile:bundlePlistPath]];
    }

    return [NSArray arrayWithContentsOfFile:plistPath];
}

- (NSIndexPath*)realIndexPathForIndex:(NSIndexPath*)idxPath
{
    NSArray *fullList = [self readFullPlist];
    NSArray *subArr = [[fullList objectAtIndex:idxPath.section] objectForKey:@"Rows"];

    int row = idxPath.row;
    int newRow = 0;

    for (NSDictionary *dic in subArr)
    {
        if ([[dic valueForKey:@"isFav"] boolValue]) {
            if (row == 0) {
                return [NSIndexPath indexPathForRow:newRow inSection:idxPath.section];
            }
            row--;
        }
        newRow++;
    }
    return idxPath;
}

然后在 didSelectRowAtIndexPath: 中传递这个转换后的 indexPath 而不是旧的:

Then in didSelectRowAtIndexPath: you pass this converted indexPath instead of the old one:

//detail.indexPath = indexPath;
detail.indexPath = [self realIndexPathForIndex:indexPath];

我想说的一点.如果可能,您应该使用唯一标识符而不是使用 indexPath.这会让事情(比如这个)变得更容易,因为你只需将该 id 传递给下一个控制器.

Something I want to mention. Instead of using the indexPath you should use an unique identifier if possible. This would make things (like this one) much easier because you only pass that id to the next controller.

这篇关于UITableView 没有显示正确的单元格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆