UITableView没有显示正确的单元格

时间:2012-06-22 14:00:47

标签: objective-c uitableview

我有2个tableViews,第一个是Main表,第二个是Favorites表。

一切都是用钳子处理的。

从第一个表格的detailView,在右上角,我创建了一个按钮,向该plist写入该单元格的值YES或NO,以便该特定单元格将显示在表格收藏夹中。 / p>

现在的问题是:

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

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

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

知道为什么吗?

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

- (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:

- (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:

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

}

使用PICS编辑

好的。我在mainTable的第一个部分选择第一个行,然后出现detailView: http://i45.tinypic.com/2lvn70x.png

然后我通过那个小星星喜欢它,在plist中将其值设置为YES

http://i45.tinypic.com/2m622a1.png

然后我进入收藏夹表,点击之前收藏的元素,它就像是这样

http://i45.tinypic.com/2m622a1.png

行。这有效。但只适用于这个

事实上,如果我尝试选择mainTable中间的一行,并尝试使用它,则detailView看起来像

http://i46.tinypic.com/9vf7k5.png

然而,在收藏夹表格中选择它看起来是这样的,空星,而它应该被收藏然后填充。如果我试图通过星形来收藏它,然后回到收藏夹表,那么mainTable中的前一行就会出现,即使它没有被收藏。

http://i47.tinypic.com/2ecdidf.png

我注意到,如果我保留第一个元素,它工作正常,但如果我删除它,它不再工作任何东西。 :\

任何帮助都受到高度赞赏,从2周开始就停止了。

4 个答案:

答案 0 :(得分:2)

您传递到indexPath中的detailController的{​​{1}}与favoritesView中的mainView不同。所以你必须做一些魔术来将过滤后的indexPath解析回原始的未过滤列表。

- (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而不是旧的:{/ p>

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

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

答案 1 :(得分:0)

我使用自定义表格单元格遇到了类似问题。通常问题出在cellForRowAtIndexPath方法中。因为你说它给你第一个单元格,我猜你正在重用你的单元格。你告诉它加载哪一个并不重要,如果你正在重复使用单元格,xcode将抛出它认为合适的第一个单元格。以下是摆脱问题的方法:

//Returns a cell to be used at a row, populates it from the holder object
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{   
    NSArray *tempPlist = [self readPlist];

    static NSString *CellIdentifier = @"Cell";
    [tableView registerNib:nib forCellReuseIdentifier:CellIdentifier];
    UITableCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    cell.favorite = [tempPlist objectAtIndex:indexPath.row];

    return cell;
}

答案 2 :(得分:0)

根据您的问题,您有两个表格视图。一个是主表,第二个是最喜欢的表。如果在主表中选择收藏夹图标,则需要将plist中的键值更改为YES,并需要重新加载这两个表。这是对的吗?

如果是,则必须按照以下步骤操作。

  
      
  1. 两个表视图单元格是一样的吗?如果不是,请在cellForRowAtIndexPath中区分它:。

  2.   
  3. 您是否正在更新plist中的收藏键值?同时选择喜欢的按钮。根据你的代码,似乎没有。

  4.   
  5. 更新plist后,需要重新加载表(主表和收藏表)。你在重新加载表吗?您   没有重新加载代码中的表,因为你写了这个   在退货声明之后。

  6.   

请检查这些条件,如果您有任何其他前景,请告诉我。

我认为这可能对您有所帮助。

答案 3 :(得分:0)

你的readPlist方法中没有,你说哪个isFav要阅读。因此,即使所有行/单元格在plist中都有自己的条目,您也无法获得该特定行的特定isFav