2

いくつかの TabBarControllers を持つ TabBar で構成されるアプリがあります。1 つのコントローラーには、NSMutableDictionary の内容を表示することになっている非常に単純なテーブルが含まれています。適切なボタンを押すと、辞書が別のコントローラーで更新され、ビューが に切り替わりUITableViewController、新しく更新されたテーブルが表示されます。

辞書が更新されていることがわかります。ただし、TableView には変更が反映されません。実際、最初にその画面に入ったときにのみ変更が表示されるようです。

[self table.reloadData] を試してみましたが、呼び出されている間、変更が に反映されませんUITableView

誰か提案はありますか?コードを投稿できてうれしいですが、何を投稿すればよいかわかりません。

更新: テーブルは、最初に表示されたときにのみ更新され、適切に更新されます。以降の表示では、単に元の内容が表示されます。

背景: テーブルビューは辞書から入力されます: appDelegate.currentFave。ViewController が TabBarController によって呼び出されるたびに、テーブルビューを更新する必要があります。

- (void)viewWillAppear:(BOOL)animated
{
    NSLog(@"in viewWillAppear");

    [super viewWillAppear:animated];

    [self loadFavesFile];
    [self.tableView reloadData];
}

// load the Favorites file from disk
- (void) loadFavesFile 
{   
// get location of file
NSString *path = [self getFavesFilePath];

// The Favorites .plist data is different from the Affirmations in that it will never be stored in the bundle. Instead,
// if it exists, then use it. If not, no problem.
if ([[NSFileManager defaultManager] fileExistsAtPath:path]) {

    // read Faves file and store it for later use...
    NSMutableDictionary *tempDict = [NSMutableDictionary dictionaryWithContentsOfFile:path];
    appDelegate.sharedData.dictFaves = tempDict;    

    // grab the latest quote. Append it to the list of existing favorites
    NSString *key = [NSString stringWithFormat:@"%d", appDelegate.sharedData.dictFaves.count + 1];

    NSString *newFave = [NSString stringWithFormat:@"%@", appDelegate.currentFave];
    [appDelegate.sharedData.dictFaves setObject:newFave forKey:key];

} else {
    NSLog(@"Favorites file doesn't exist");
    appDelegate.sharedData.dictFaves = nil;     
}
}


// this gets invoked the very first call. Only once per running of the App.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// reuse or create the cell
static NSString *cellID = @"cellId";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:cellID];  
if (cell == nil) {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID];
}

// allow longer lines to wrap
cell.textLabel.numberOfLines = 0; // Multiline
cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
cell.textLabel.font = [UIFont fontWithName:@"Chalkduster" size:(16)];
cell.textLabel.textColor = [UIColor yellowColor];   

// NOTE: for reasons unknown, I cannot set either the cell- or table- background color. So it must be done using the Label.

// set the text for the cell
NSString *row = [NSString stringWithFormat:@"%d", indexPath.row + 1];
cell.textLabel.text = [appDelegate.sharedData.dictFaves objectForKey:row];
return cell;    
}
4

4 に答える 4

1

問題が見つかりました。View ControllerでTableViewを適切に初期化および割り当てていませんでした。下記参照

- (void)viewDidLoad
{
   [super viewDidLoad];

   tableView = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]     style:UITableViewStylePlain];

   tableView.dataSource = self;
   tableView.delegate = self; 
   tableView.backgroundColor=[UIColor blackColor];
   self.view = tableView;
}
于 2012-02-17T01:18:07.933 に答える
0

Interface Builder 接続が適切にセットアップされていることを確認する必要がありますが、この問題が実際にどのように聞こえるかは、ステートメントcellForRowAtIndexPath:内にUITableViewCell セットアップ コードがあるためです。if(cell == nil)それはあってはならないことです。説明させてください。セルのリストがあり、各セルのタイトルを という配列の文字列に設定したい場合myArray、(間違った) コードは次のようになります。

- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cellIdentifier"];
    if (cell == nil) {
        // No cell to reuse => create a new one
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"cellIdentifier"] autorelease];

        [[cell textLabel] setText:[myArray objectAtIndex:[indexPath row]]];
    }
    return cell;
}

そのロジックの問題がわかりますか? セルは、再利用可能なセルが見つからない場合にのみ更新されたタイトルを取得します。これは、あなたの場合、状況のように聞こえます。Apple は、呼び出されるたびに「新しい」セルを作成する必要があると述べていますcellForRowAtIndexPath:。これは、すべてのセットアップ コードをチェックのに置くことを意味します。if(cell == nil)

この例を続けると、適切なコードは次のようになります。

- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cellIdentifier"];
    if (cell == nil) {
        // No cell to reuse => create a new one
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"cellIdentifier"] autorelease];
    }

    [[cell textLabel] setText:[myArray objectAtIndex:[indexPath row]]];
    return cell;
}

このようにして、再利用可能なセルが見つかったかどうかに関係なく、セルに適切な文字列が割り当てられるため、呼び出しreloadDataによって目的の効果が得られます。

于 2012-01-31T01:20:44.590 に答える
0

作成したコードが正しいと仮定すると、 を使用したいと思います[self.table reloadData]。あなたは.間違った場所にいます。

于 2012-01-31T00:48:10.903 に答える
0

私は昨日同じ問題を抱えていました.Interface Builderで間違ったファイル所有者を設定し、テーブルビューのデータソースとデリゲートを適切に設定していなかったことがわかりました.

Interface Builder に入り、ファイルの所有者を右クリックしてみてください。何かが正しく接続されていないかどうかが表示されます。

于 2012-01-31T00:49:41.573 に答える