UITableView 自定义节标题,重复问题
我在为自定义 UITableView 部分标题设置动画时遇到问题。
目标是创建可折叠的部分。
当我第一次点击自定义标题时,它会按预期进行动画处理,但此后每次它都会在原始位置留下重复项并为另一个进行动画处理。
图片示例:
- (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UIView* customView = [[[UIView alloc]initWithFrame:CGRectMake(10.0, 0.0, 300.0, 44.0)]autorelease];
customView.backgroundColor = [UIColor lightGrayColor];
UILabel * headerLabel = [[[UILabel alloc] initWithFrame:CGRectZero] autorelease];
headerLabel.backgroundColor = [UIColor clearColor];
headerLabel.opaque = NO;
headerLabel.textColor = [UIColor darkGrayColor];
headerLabel.font = [UIFont boldSystemFontOfSize:16];
headerLabel.frame = CGRectMake(10, 7, 260.0, 44.0);
headerLabel.textAlignment = UITextAlignmentCenter;
NSDictionary *dictionary = [self.data objectAtIndex:section];
headerLabel.text = [dictionary objectForKey:@"Title"];
[customView addSubview:headerLabel];
// add button to right corner of section
UIButton* headerButton = [[UIButton alloc] initWithFrame:CGRectMake(10, 0, 320, 44)];
headerButton.center = CGPointMake( 160.0, 22.0);
headerButton.backgroundColor = [UIColor clearColor];
headerButton.tag = section;
[headerButton addTarget:self action:@selector(expandSection:) forControlEvents:UIControlEventTouchUpInside];
[customView addSubview:headerButton];
return customView;
}
我的动画方法:
- (void) expandSection:(id)sender {
if (expandedSection == [sender tag]) {
expandedSection = -1;
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:[sender tag]] withRowAnimation:UITableViewRowAnimationNone];
}else if (expandedSection == -1){
expandedSection = [sender tag];
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:[sender tag]] withRowAnimation:UITableViewRowAnimationNone];
}else{
[self.tableView beginUpdates];
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:expandedSection] withRowAnimation:UITableViewRowAnimationNone];
expandedSection = [sender tag];
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:[sender tag]] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates];
}
//[self.tableView reloadData];
}
我不太确定发生了什么,但实例表明我需要释放某些内容。我尝试了一些方法,但我无法弄清楚这一点。任何人对此提供帮助都会很棒!
编辑:我认为问题是 reloadSections 导致自定义视图实例化。我无法释放视图,因为我需要它作为更新动画的参考。我能做些什么来解决这个问题有什么想法吗?
I am having trouble animating a custom UITableView section header.
The goal was to create collapsable sections.
When I tap on the custom header the first time it animates as expected, however every time after that it leaves a duplicate in the original location and animates another.
Image Example:
- (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UIView* customView = [[[UIView alloc]initWithFrame:CGRectMake(10.0, 0.0, 300.0, 44.0)]autorelease];
customView.backgroundColor = [UIColor lightGrayColor];
UILabel * headerLabel = [[[UILabel alloc] initWithFrame:CGRectZero] autorelease];
headerLabel.backgroundColor = [UIColor clearColor];
headerLabel.opaque = NO;
headerLabel.textColor = [UIColor darkGrayColor];
headerLabel.font = [UIFont boldSystemFontOfSize:16];
headerLabel.frame = CGRectMake(10, 7, 260.0, 44.0);
headerLabel.textAlignment = UITextAlignmentCenter;
NSDictionary *dictionary = [self.data objectAtIndex:section];
headerLabel.text = [dictionary objectForKey:@"Title"];
[customView addSubview:headerLabel];
// add button to right corner of section
UIButton* headerButton = [[UIButton alloc] initWithFrame:CGRectMake(10, 0, 320, 44)];
headerButton.center = CGPointMake( 160.0, 22.0);
headerButton.backgroundColor = [UIColor clearColor];
headerButton.tag = section;
[headerButton addTarget:self action:@selector(expandSection:) forControlEvents:UIControlEventTouchUpInside];
[customView addSubview:headerButton];
return customView;
}
My Animation Method:
- (void) expandSection:(id)sender {
if (expandedSection == [sender tag]) {
expandedSection = -1;
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:[sender tag]] withRowAnimation:UITableViewRowAnimationNone];
}else if (expandedSection == -1){
expandedSection = [sender tag];
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:[sender tag]] withRowAnimation:UITableViewRowAnimationNone];
}else{
[self.tableView beginUpdates];
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:expandedSection] withRowAnimation:UITableViewRowAnimationNone];
expandedSection = [sender tag];
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:[sender tag]] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates];
}
//[self.tableView reloadData];
}
I am not exactly sure whats going on, but the instances suggest that I need to dealoc something. I've tried a few things but I can't figure this out. Anyone help on this would be great!
Edit: I believe the problem is that reloadSections is causing the custom view to instance. I can't release the view because I need it as a reference to do the update for the animation. Any ideas on what I can do to fix this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
找到解决方案。
每次更改之前都需要重新加载该表。这样,表就处于进行任何更改之前的最新状态。
添加
[self.tableView reloadData];
作为“expandSection”方法中的第一个条目。
代码:
Solution found.
The table needed to be reloaded before every change. This way the table is at the latest state before making any changes.
add
[self.tableView reloadData];
as the fist entry in the "expandSection" method.
CODE:
我遇到了类似的问题,这是由于使用动态高度单元引起的。我有一个可扩展的自定义标题视图,当我更新 tableView 以插入和删除该部分的关联行(意味着它们正在展开,分别折叠)时,该部分标题是 UITableViewHeaderFooterView 的子类没有被回收。所以基本上一个新的被分配并添加到旧的之上,导致视图重叠。单元标识符已正确设置,因此一定是其他内容。当我删除
tableView.sectionHeaderHeight = UITableViewAutomaticDimension
并实现func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat
视图得到了正确的回收,并且每个部分仅显示一个标题视图。我发现实际有效的另一个解决方案是使用
UITableViewCell
而不是UITableViewHeaderFooterView
,当您返回func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int )-> UIView?
你只需返回cell.contenView
,这将起作用,因为该方法需要返回一个UIView,并且由于UITableViewCell的contentView
是一个UIView,所以它可以起作用很好。背后的想法是通过 UITableViewCell 使用 UITableView 的回收机制,并在配置后返回其内容。结论。当与自调整大小的 tableView 单元格和
UITableViewAutomaticDimension
一起使用而不是手动计算单元格高度时,很可能由UITableViewHeaderFooterView
引起的问题。I had a similar issue which was caused by using dynamic height cells. I had an expandable custom header view and when I was updating tableView to insert and remove the associated rows of the section (meaning that they were expanding, respectively collapsing), the section header which was a subclass of
UITableViewHeaderFooterView
was not recycled. So basically a new one was allocated and added over the old one resulting in overlapping views. The cell identifier was properly set so must have been something else. When I removedtableView.sectionHeaderHeight = UITableViewAutomaticDimension
and implementedfunc tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat
the view got properly recycled and only one header view was displayed for each section.Another solution that I turned out to actually work was to use
UITableViewCell
instead ofUITableViewHeaderFooterView
and when you return infunc tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?
you justreturn cell.contenView
, this will work because the method requires to return a UIView and since thecontentView
of the UITableViewCell is a UIView it works just fine. The idea behind is to use the recycling mechanism of UITableView through UITableViewCell and just return its content after you configure it.Conclusion. The problem it is very possible to be caused by
UITableViewHeaderFooterView
when is used with self sizing tableView cells andUITableViewAutomaticDimension
instead of manually calculating cell height.