2010-04-26 68 views
2

UPDATE 4.0的UITableView節頭和頁腳節不更新(重繪問題)

好像的iOS 4.0改變了這裏的東西。根據我的第一次快速檢查,相同的代碼在所描述的場景中爲部分標題生成不正確的背景與4.0一起工作!

原始

我有一個自定義頁眉和頁腳視圖一個UITableView分組風格。在頁腳內部放置一個UILabel和一個UIButton。

單擊按鈕隱藏或顯示一些行,更新頁腳視圖中的UILabel並最終調整頁腳視圖的大小。

基本上一切工作正常。但標籤上的文字未在屏幕上更新。它在UILabel文本屬性中進行了更新,但只有在將部分頁腳滾出可見區域並將其向後滾動時纔會更新。所以這是UITableView的典型重繪問題。

我試過每種方法來強制更新像needsLayout等沒有幫助。

我已經看到一些相關的問題,但有一些不同的行爲,沒有解決方案。任何幫助/想法?

感謝格爾德

UPDATE:第頁腳發生

我的問題,所以這裏是我的viewForFooterInSection。

基本上我想崩潰/展開一個部分,但不是完全(這是一件容易的事),而只是空的單元格(ItemSize空)。頁腳視圖如果已摺疊,則較大;如果展開,則會縮小。此外,標籤文本將改變。

- (UIView *)tableView: (UITableView *)tableView viewForFooterInSection: (NSInteger)section{ 
NSLog(@"viewForFooterInSection section:%i", section); 

UIButton *myView; 
UILabel *label; 

if ([[[self.sectionStatus objectAtIndex:section] valueForKey:@"collapseStatus"] isEqual:@"collapse"]){ 
    myView = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 320, 52)]; 
    [myView setBackgroundImage:[UIImage imageNamed:@"ItemViewFooter.png"] forState:UIControlStateNormal]; 
    label = [[UILabel alloc] initWithFrame:CGRectMake(20, 32, 300, 20)]; 
    label.text = NSLocalizedString(@"list_expand",@""); 
} else { //is expanded 
    myView = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 320, 21)]; 
    [myView setBackgroundImage:[UIImage imageNamed:@"ListCollapseExpand.png"] forState:UIControlStateNormal]; 
    label = [[UILabel alloc] initWithFrame:CGRectMake(20, 1, 300, 20)]; 
    label.text = NSLocalizedString(@"list_collapse",@""); 
} 

myView.tag=section; 
[myView addTarget:self action:@selector(collapseExpandAction:) forControlEvents:UIControlEventTouchUpInside]; 
myView.backgroundColor = [UIColor clearColor]; 
myView.adjustsImageWhenHighlighted = NO; 
myView.showsTouchWhenHighlighted = YES; 

label.textColor = FONTCOLOR; 
label.font = [UIFont systemFontOfSize:14]; 
label.numberOfLines = 1; 
label.textAlignment = UITextAlignmentCenter; 
label.backgroundColor = [UIColor clearColor]; 
[myView addSubview:label]; 
return myView; 

};

在按鈕操作方法中,我存儲部分摺疊/展開的狀態和顯示的行數。比我刪除或插入行。 (它必須與插入/刪除,因爲我需要動畫)。

- (void) collapseExpandSection: (NSInteger) section{ 
NSMutableArray *paths = [NSMutableArray arrayWithCapacity:10]; 
NSInteger row; 
NSInteger numberOfDisplayedItems=[[[self.sectionStatus objectAtIndex:section] valueForKey:@"numberOfDisplayedRows"] intValue]; 
id <NSFetchedResultsSectionInfo> sectionInfo = [[fetchedResultsController sections] objectAtIndex:section]; 
NSInteger numberOfAllItems=[sectionInfo numberOfObjects]; 
Item *tmpItem=nil; 
NSSet *itemsWithSizes=nil; 

//filter not used cells 
for (row = 0; row < numberOfAllItems; row++) { 
    tmpItem=[fetchedResultsController objectAtIndexPath:[NSIndexPath indexPathForRow:row inSection:section]]; 
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"itemSize != nil"]; 
    NSSet *itemsWithSizes = [tmpItem.itemSizes filteredSetUsingPredicate:predicate]; 
    if ([itemsWithSizes count]==0){ 
     [paths addObject:[NSIndexPath indexPathForRow:row inSection:section]]; //all unused cells 
    }; 
} 

if (numberOfDisplayedItems == numberOfAllItems){ //currently all shown => Collapse 
    [self.tableView beginUpdates]; 
    [[self.sectionStatus objectAtIndex:section] setValue:[NSNumber numberWithInt:(numberOfDisplayedItems-[paths count])] forKey:@"numberOfDisplayedRows"]; 
    [[self.sectionStatus objectAtIndex:section] setValue:@"collapse" forKey:@"collapseStatus"]; 
    [self.tableView deleteRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationFade]; 
    [self.tableView endUpdates]; 
} else { //Not all shown so expand with the unused cells 
    [[self.sectionStatus objectAtIndex:section] setValue:[NSNumber numberWithInt:(numberOfDisplayedItems+[paths count])] forKey:@"numberOfDisplayedRows"]; 
    [[self.sectionStatus objectAtIndex:section] setValue:@"expand" forKey:@"collapseStatus"]; 
    [self.tableView beginUpdates]; 
    [self.tableView insertRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationFade]; 
    [self.tableView endUpdates]; 
} 
return; 

};

這樣做一切正常。塊開始/結束更新後,將爲每個節調用viewForFooter,並且標籤文本在屬性中設置爲正確。但是,顯示不能正確更新。一旦重新顯示被強制(滾動顯示滾動),顯示就OK。

回答

4

有2個問題。
第一個問題是部分頁腳未更新。 更新後請嘗試致電[tableView reloadData][tableView reloadSections:sections withRowAnimation:UITableViewRowAnimationFade](可能與達拉)。
第二個問題是myViewlabel中的內存泄漏。 你爲什麼在使用按鈕的內部標籤時使用標籤? P.S.因爲它是工廠,所以不要直接分配UIButton對象。改爲撥打[UIButton buttonWithType:UIButtonTypeCustom]

Upd:另一種更新方法是直接通過訪問頁腳視圖來更新頁腳。

- (void) collapseExpandSection: (NSInteger) section{ 

檢查節actualy你的按鈕

- (void) collapseExpandSection: (UIButton*) sender{ 
// Do update of sender here 
// Do other stuff 
} 

你也可以嘗試下招:在委託創作的UIView對象,加上它的按鈕和標籤和instaed返回BUTTOM視圖本身。

+0

感謝您的回覆,Skie。 reloadData和reloadSection的問題是,兩種方法都會銷燬插入/刪除行的動畫。 內存泄漏是因爲我縮短了這個例子。 該標籤用於輕鬆控制佈局和位置。 那麼是否有任何想法得到沒有重新加載數據的章節頁腳/節頭的更新?這是不可能的,所有複雜的動畫都不需要完全重新加載,並且只需更改UIlabel的文本,我必須執行全部重新加載以及所有負面影響?我不敢相信。 – Gerd 2010-04-26 17:05:35

+0

嘿!至少有一個工作的解決方法。如果您在章節頁腳視圖中放置按鈕,則按鈕的框架將在按鈕的操作方法中重新顯示。是的,只有!按鈕的框架。可能是因爲按鈕的刷新與表格視圖完全無關。 所以我定義了我的按鈕來填充完整的頁腳視圖。比我把標籤作爲按鈕的子視圖。最後,我在按鈕的操作方法(collapseExpandAction:(UIButton)sender)中更新所有這些。 再次感謝Skie指引我走向正確的方向! – Gerd 2010-04-27 09:16:44

3

我的問題是,我正在擴大部分標題顯示一個搜索欄,但它不會重畫視圖,直到我滾動UITableView。

我有我自己的SectionHeader類的子類UIView和控制搜索的東西。

我的動畫後,我只是用它來強制更新。它不漂亮,但它的工作原理。

CGPoint point = CGPointMake(((UIScrollView *)self.superview).contentOffset.x, 
          ((UIScrollView *)self.superview).contentOffset.y+1); 
[((UIScrollView *)self.superview) setContentOffset:point animated:NO]; 

point = CGPointMake(((UIScrollView *)self.superview).contentOffset.x, 
        ((UIScrollView *)self.superview).contentOffset.y-1); 
[((UIScrollView *)self.superview) setContentOffset:point animated:NO]; 

基本上強制UITableView向下滾動1個像素和1個像素。

0

我有一個問題就像這樣,我想在插入新行後更新節頭。我發現調用tableView reloadSections()方法後,我調用insertRows方法爲我工作(兩個調用在同一個tableView更新塊中)之後,動畫設置爲.None。我得到了我想要的插入動畫,並更新了部分標題。