1

我有 2 个表视图,第一个是主表,第二个是收藏夹表。

一切都用 plist 处理。

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

现在的问题是:

  • 我从第一个表中选择一行,即主表。detailView 出现,我点击 UIBarButton 使该细节成为收藏夹(因此星形图像作为图像出现在按钮中,让用户知道该单元格是收藏夹)。好的。
  • 我去第二张表,最喜欢的一张,选择以前收藏的单元格,我看到星号是空的,然后布尔值设置为 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];
    }

}

用图片编辑

可以,然后呢。我选择mainTable第一部分的 第一行,出现detailView:

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

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

好的。这行得通。但仅限于此

事实上,如果我尝试选择主表中间的一行,并尝试收藏它,detailView 看起来像

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

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

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

4

4 回答 4

2

indexPath你传递给你的in 和那个detailControllerinfavoritesView不一样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而不是旧的:

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

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

于 2012-06-29T00:27:11.247 回答
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;
}
于 2012-06-22T19:35:54.787 回答
0

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

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

  1. 两个表格视图单元格是否相同?如果不是,请在 cellForRowAtIndexPath: 中进行区分。

  2. 你在更新 plist 中最喜欢的键值吗?选择收藏夹按钮时。根据您的代码,它似乎不是。

  3. 更新 plist 后,需要重新加载两个(主表和最喜欢的表)表。你在重新加载表格吗?您没有在代码中重新加载表,因为您已经在 return 语句之后编写了这个。

请检查这些条件,如果您有任何其他潜在客户,请告诉我。

我认为这可能对你有帮助。

于 2012-06-27T05:58:47.207 回答
0

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

于 2012-06-27T20:57:44.257 回答