2009-08-18 57 views
2

我正在生產iPhone應用程序,其中的部分界面完全像'最受歡迎'部分的iPhone YouTube應用程序。UITableView將無法正確更新(即使調用reloadData)

這種「流行」部分從標籤欄在底部訪問,並在頂部的導航欄包含UISegmentedControl選擇「今天,這周,月等..」

因爲大多數的該應用程序由包含非常類似結構化內容的單元格的UITableView組成,我創建了一個通用MyAppTableViewController,它繼承UITableViewController。我的'受歡迎的'部分因此由熱門桌面控制器,它繼承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!除非!...一個單元格從視圖中滾動出來,然後回到視圖中......然後它變了!

我已經做了很多關於這個問題的搜索,對於類似問題的一個建議是將[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; 
} 

上面的代碼是在MyAppTableViewController這也是其中myItemList駐留。

+0

發佈用於填充你的細胞 – Daniel

+0

@Daniel的C頌歌 - 我已經更新了問題的要求。 – IAmFledge

+2

與您的問題無關,但您可以更輕鬆地獲取itemIndex:NSUInteger itemIndex = [indexPath row]。 –

回答

5

您的-performSelectorOnMainThread:代碼適用於在後臺線程上對模型類進行更改。 UI事件(包括-reloadData)需要在主線程上發生。如果你不使用後臺線程,那麼這是不必要的。如果你是,像這樣的東西是強制性的。

如果您正在更改特定單元格的值,則您實現的方式是更改單元格本身。在iPhone上,單元格是全視圖(與Mac不同),所以如果您想更改數據,只需更改其數據並致電-setNeedsDisplay即可。您可以使用-cellForRowAtIndexPath:獲取給定位置的單元格(視圖)。您可以通過使用-indexPathsForVisibleRows-visibleCells來確定給定的單元格是否在屏幕上。

這是非常罕見的需要撥打-reloadData。如果你扔掉所有東西並加載完全不同的數據,你只應該這樣做。相反,您應該使用插入/刪除例程來添加/刪除行,並且您應該在數據更改時更新現有行的視圖。

+0

Hi Rob。感謝您的回答。每個選定的片段索引都會導致一個不同的xml文件被解析(對於'今日'/'周'/'月'),這只是我想要顯示的選定xml的內容,而不是將其添加到現有單元格中。我應該在這種情況下不使用reloadData嗎? – IAmFledge

+1

這應該是-reloadData。您是在主線程上解析,還是在後臺更改模型數據? –

+0

因爲我很新的iPhone/ObjC編程,我不完全確定iPhone OS如何處理線程。 (例如,我不知道您在界面構建器中創建的連接是否會導致新線程在後臺啓動)。 但我沒有明確聲明一個新的線程。我只是有我的AppDelegate包含我的UITabBarController * tabBarController(我沒有代碼,它只是連接在I.B.)和我的控制器類,如問題中所述。 在I.B.我的TabBarController擁有一些NavigationControllers的擁有權,每個擁有... – IAmFledge

0

你試過[tableView setNeedsDisplay:YES]

1

我有這個相同的問題,這是因爲我有一個[tableView beginUpdates]調用後沒有endUpdates調用。

-1

調用-reloadData之後,你是否收到tableView:numberOfRowsInSection的回調函數? 我幾乎可以肯定,那就是self.myTableView這裏爲零:

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

}

相關問題