iphone - UITableView 节标题和节页脚未更新(重绘问题)

标签 iphone uitableview

更新4.0

似乎 iOS 4.0 在这里改变了一些东西。根据我的第一次快速检查,在所描述的场景中为节标题生成不正确背景的相同代码正在使用 4.0!

原创

我有一个带有自定义页眉和页脚 View 的 UITableView 分组样式。在页脚内我放置了一个 UILabel 和一个 UIButton。

单击按钮会隐藏或显示某些行,更新页脚 View 中的 UILabel,并最终调整页脚 View 的大小。

基本上一切都工作正常。但屏幕上的标签文本并未更新。它在 UILabel 文本属性中更新,但只有当我将节页脚滚动到可见区域之外并将其向后滚动时,它才会更新。所以这是一个典型的 UITableView 重绘问题。

我尝试了各种方法来强制更新,例如needsLayout等,但没有任何帮助。

我看到了一些相关的问题,但有一些不同的行为,并且没有解决方案。有什么帮助/想法吗?

谢谢,格尔德

更新:

我的问题发生在节页脚上,所以这是我的 viewForFooterInSection。

基本上我想折叠/展开一个部分,但不是完全折叠/展开(这是一件容易的事情),而只是空单元格(ItemSize 为空)。 footerView 折叠时会很大,展开时会缩小。此外,标签文本也会改变。

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

};

总的来说,完成所有这些工作都很好。在 block 开始/结束更新之后,为每个部分调用 viewForFooter,并且在属性中正确设置标签文本。但是,显示无法正确更新。一旦强制重新显示(向外滚动-向内滚动),显示就正常。

最佳答案

有 2 个问题。
第一个问题是该部分页脚未更新。 尝试在更新后调用 [tableView reloadData][tableView reloadSections:sections withRowAnimation:UITableViewRowAnimationFade](可能使用 dalay)。
第二个问题是 myViewlabel 中的内存泄漏。 另外,当您可以使用按钮的内部标签时,为什么还要使用标签? 附:不要直接分配 UIButton 对象,因为它是工厂对象。改为调用 [UIButton buttonWithType:UIButtonTypeCustom]

更新:另一种更新方法是通过访问页脚 View 直接更新页脚。

- (void) collapseExpandSection: (NSInteger) section{

检查该部分实际上是您的按钮

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

您还可以尝试下一个技巧:在委托(delegate)中创建 UIView 对象,在其上添加按钮和标签,然后返回按钮 View 本身。

关于iphone - UITableView 节标题和节页脚未更新(重绘问题),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2713884/

相关文章:

iphone - 如何修复 ‘NSObjectInaccessibleException’ 获取请求在被 NSManagedObjectContext 使用之前无法响应 -entity'

ios - 具有动态高度和自动布局的 UITableViewCell - 单元格中的方形 View

ios - TableView 渲染其单元格的内部过程是什么

ios - 如果 UITextField 具有 inputAccessoryView,则 UIKeyboardDidShowNotification 选择器调用两次

ios - Parse.com 的一些列未在 segue 上更新

ios - 如何在 iOS、Objective C 中的 TableView 的每个部分中仅实现单个单元格选择

ios - 使用从 NSURLConnection 检索到的数据填充 UITableView

ios - UITableViewDelegate 在 iOS 中是否有类似 tableViewWillEndDisplayingCell 的方法?

iphone - 更改 NSString 中的 html 标签

iphone - NSUnknownKeyException - 设置值 : forUndefinedKey in classfile