1

私は 2 つの tableViews を持っています。1 つ目はメイン テーブルで、2 つ目はお気に入りテーブルです。

すべてがplistで処理されます。

最初のテーブルの detailView から、右上隅に、そのセルの値 YES または NO を plist に書き込むボタンを作成して、その特定のセルがテーブルのお気に入りに表示されるようにします。

問題は次のとおりです。

  • メインのテーブルである最初のテーブルから行を選択します。detailView が表示され、その詳細をお気に入りにする UIBarButton をタップします (そのため、星の画像が画像としてボタンに表示され、セルがお気に入りであることをユーザーに知らせます)。わかった。
  • 2番目のテーブルであるお気に入りのテーブルに移動し、以前にお気に入りにしたセルを選択すると、星が空であることがわかり、ブール値がNOに設定されます(そして、少し前にお気に入りにしたため、YESに設定されるはずです)。

firstTableの最初の項目をお気に入りに追加すると、最初のビューですべてお気に入りに追加した後でも、2 番目のビューの他のセルが正しく表示されることに気付きました。

少しトリッキーですが、それは起こっています。

理由はありますか?

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に設定します

次に、お気に入りテーブルに移動し、以前にお気に入りにした要素をクリックすると、次のように表示されます

わかった。これは機能します。しかし、これだけです!

実際、mainTable の真ん中にある行を選択しようとして、それをお気に入りにしようとすると、detailView は次のようになります。

しかし、お気に入りテーブルでそれを選択すると、空の星のように見えますが、お気に入りに追加してから埋める必要があります。スターを使用してお気に入りに追加しようとして、お気に入りテーブルに戻ると、お気に入りに追加されていなくても、mainTable の前の行が表示されます。

最初の要素を保持すると正常に機能することに気付きましたが、削除すると何も機能しなくなります。:\

どんな助けでも大歓迎です、2週間から立ち往生しています。

4

4 に答える 4

2

あなたがあなたのインにindexPath渡すのは、のあなたと同じではありません。したがって、フィルタリングされたものを元のフィルタリングされていないリストに解析して戻すには、何らかの魔法をかける必要があります。detailControllerfavoritesViewmainViewindexPath

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

あなたの質問によると、2 つのテーブル ビューがあります。1 つはメイン テーブル、もう 1 つはお気に入りのテーブルです。メイン テーブルでお気に入りのアイコンを選択した場合、plist のキー値を に変更し、YES両方のテーブルをリロードする必要があります。これは正しいですか?

はいの場合は、次の手順に従う必要があります。

  1. 両方のテーブル ビュー セルは同じですか? いいえの場合は、cellForRowAtIndexPath: で区別してください。

  2. plist のお気に入りのキー値を更新していますか? お気に入りボタンを選択中。あなたのコードによると、NOのようです。

  3. plist を更新したら、両方 (メイン テーブルとお気に入りのテーブル) のテーブルをリロードする必要があります。テーブルをリロードしていますか?returnステートメントの後にこれを書いているため、コードでテーブルをリロードしていません。

これらの条件を確認し、他に見込みがある場合はお知らせください。

これはあなたに役立つかもしれないと思います。

于 2012-06-27T05:58:47.207 に答える
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

あなたのreadPlistメソッドにはありませんでしたか?したがって、すべての行/セルが plist に独自のエントリを持っていても、その特定の行の特定の isFav を取得していません

于 2012-06-27T20:57:44.257 に答える