2009-08-18 5 views
2

iPhoneのYouTubeアプリのの「Most Popular」の部分のようなインターフェースの一部をiPhoneアプリとして制作しています。UITableViewが正しく更新されない(reloadDataの呼び出しでも)

この「人気」のセクションは、一番下にタブバーからアクセスし、上部のナビゲーションバーには、選択しUISegmentedControlが含まれている「今週、今日、月など..」

のほとんどのため、このアプリは、非常に似た構造のコンテンツを含むセルを持つUITableViewsで構成されています。MyAppTableViewControllerを継承しています。UITableViewControllerを継承しています。私の「 popular」セクションは、PopularTableViewControllerで構成され、MyAppTableViewControllerを継承しています。実際のUITableViewは、MyAppTableViewController内にあります。

PopularTableViewControllerメソッドを有する。

- (void) segmentChangeTimeframe:(id)sender { 
    UISegmentedControl *segCtl = sender; 
    if([segCtl selectedSegmentIndex] == 0) 
    { 
     // Call [self parse-xml-method-which-resides-in-MyAppTableViewController] 
    } 
    //... ... ... 
} 

MyAppTableViewControllerはNSXMLParserを利用し、したがって、コードがあります

- (void)parserDidEndDocument:(NSXMLParser *)parser { 
    [self.myTableView reloadData]; 
} 

(更新他の方法があるがテーブルビューがそのデータを取得するデータ構造)

コンソール出力コードをxml解析メソッドに入れました。実行すると、異なるセグメントを選択すると正しいxmlファイルが正しく解析され、データ構造に正しい値が含まれているように見えます。

問題は、表のセルの内容が変更されないことです。 grr!無条件!...セルが表示外にスクロールされ、ビューに戻ります。

私はこの問題について多くの検索を行いました。同様の問題に対する1つの提案は、[self.myTableView reloadData]を独自のメソッドに配置することでした。 をmyReloadDataMethodしてから使用してください。

[self performSelectorOnMainThread:@selector(myReloadDataMethod) withObject:nil waitUntilDone:NO]; 

私はparserDidEndDocumentメソッドに上記のコードを配置してみました、それは全く違いが行われていません!私は絶対に困惑していて、誰かがここで何が起こっているか考えているのだろうかと思っています。

更新:細胞を移入する

コードを用いて行われる:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    static NSString *MyIdentifier = @"MyIdentifier"; 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier]; 
    if (cell == nil) { 
     cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:MyIdentifier] autorelease]; 
    } 

    // Set up the cell 
    int itemIndex = [indexPath indexAtPosition: [indexPath length] - 1]; 
    NSString *artistName = [[myItemList objectAtIndex: itemIndex] objectForKey: @"itemA"]; 
    NSString *mixName = [[myItemList objectAtIndex: itemIndex] objectForKey: @"itemB"]; 
    cell.textLabel.text = itemA; 
    cell.detailTextLabel.text = itemB; 
    cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton; 

    return cell; 
} 

上記のコードはmyItemListが存在する場所でもあるMyAppTableViewControllerです。

+0

は、あなたがあなたの細胞 – Daniel

+0

@Danielを取り込むために使用するC頌歌を投稿 - 要求されたように私は質問を更新しました。 – IAmFledge

+2

あなたの問題に関係はありませんが、itemIndexをもっと簡単に取得できます:NSUInteger itemIndex = [indexPath row]。 –

答えて

5

-performSelectorOnMainThread:コードは、バックグラウンドスレッドでモデルクラスを変更したときのコードです。 UIイベント(-reloadDataを含む)がメインスレッド上で発生する必要があります。バックグラウンドスレッドを使用していない場合、これは不要です。もしあなたがそうであれば、それは義務的です。

あなたが特定のセルの値を変更している場合、あなたはそれを達成方法は、細胞自体を変更することです。 iPhoneでは、セルは完全なビューです(Macとは異なります)。データを変更する場合は、データを変更して-setNeedsDisplayに電話してください。 -cellForRowAtIndexPath:を使用して、特定の場所のセル(ビュー)を取得できます。 -indexPathsForVisibleRowsまたは-visibleCellsを使用して、特定のセルがオンスクリーンであるかどうかを判断できます。

-reloadDataを呼び出す必要がありますすることは非常に稀です。すべてを捨てて完全に異なるデータをロードしている場合にのみ行うべきです。代わりに、挿入/削除ルーチンを使用して行を追加/削除し、データが変更されたときに既存の行のビューを更新するだけです。

+0

こんにちは。ご回答有難うございます。選択された各セグメントインデックスは、( 'Today'/'Week'/'Month'のために)別のxmlファイルを解析し、既存のセルに追加するのではなく、表示する必要がある選択されたxmlのコンテンツに過ぎません。この場合、reloadDataを使用しないでください。 – IAmFledge

+1

これは-reloadDataである必要があります。メインスレッドを解析していますか、またはモデルデータをバックグラウンドで変更していますか? –

+0

私はiPhone/ObjCプログラミングにはかなり新しいので、iPhone OSがスレッドをどのように処理するかは完全にはわかりません。 (たとえば、インタフェースビルダーで行った接続によって、新しいスレッドがバックグラウンドで実行されるかどうかはわかりません)。 しかし、私は明示的に新しいスレッドを宣言していません。私はちょうど私のUITabBarController * tabBarController(私はコードがない、それはちょうどI.B.に接続されている)と質問に記載されているように私のコントローラクラスを含む私のAppDelegateを持っています。 I.B.私のTabBarControllerは、いくつかのNavigationControllersの所有権、 – IAmFledge

0

あなたが[tableView setNeedsDisplay:YES]を試してみましたか?

1

私はこの同じ問題を抱えていた、と私は後endUpdatesコールなし[のtableView beginUpdates]コールがあったのでそれがでした。 -reloadDataを呼び出した後

-1

は、あなたがのtableViewにコールバックを受け取るん:numberOfRowsInSectionを:? 私はself.myTableViewがここにnilであることを、ほとんど確信している:

- (void)parserDidEndDocument:(NSXMLParser *)parser { 
[self.myTableView reloadData]; 

}

関連する問題