我有UITableView
个自定义单元格和自定义标题。当我在编辑时移动一个单元格时,它会弹出标题视图。
如何将标题视图保留在所有单元格的顶部?
该应用程序使用故事板,以防万一。
它看起来如何? https://www.dropbox.com/s/wg8oiar0d9oytux/iOS%20SimulatorScreenSnapz003.mov
这是我的代码:
[...]
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"ListCell";
ListCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
int handleSection = [self sectionToHandle:indexPath.section];
switch (handleSection)
{
case PrivateLists:
{
if (tableView.isEditing && (indexPath.row == self.privateLists.count))
{
cell.textField.text = NSLocalizedString(@"Lägg till ny lista", nil);
cell.textField.enabled = NO;
cell.textField.userInteractionEnabled = NO;
cell.accessoryType = UITableViewCellAccessoryNone;
cell.editingAccessoryView.hidden = YES;
}
else
{
List *list = [self.privateLists objectAtIndex:indexPath.row];
cell.textField.text = list.name;
cell.textField.enabled = YES;
cell.textField.userInteractionEnabled =YES;
cell.backgroundColor = [UIColor clearColor];
cell.onTextEntered = ^(NSString* enteredString){
list.name = enteredString;
UpdateListService *service = [[UpdateListService alloc]initServiceWithList:list];
[service updatelistOnCompletion:
^(BOOL success){
DLog(@"Updated list");
NSIndexPath *newPath = [NSIndexPath indexPathForRow:0 inSection:indexPath.section];
[self.tableView moveRowAtIndexPath:indexPath toIndexPath:newPath];
[self moveListToTop:list.ListId newIndexPath:newPath];
justMovedWithoutSectionUpdate = YES;
}
onError:
^(NSError *error){
[[ActivityIndicator sharedInstance] hide];
[[ErrorHandler sharedInstance]handleError:error fromSender:self];
}];
};
}
}
break;
default:
return 0;
break;
}
return cell;
}
-(UIView *)tableView:(UITableView *)aTableView viewForHeaderInSection:(NSInteger)section
{
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 22)];
UILabel *textLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 0, 300, 21)];
[textLabel setFont:[[AXThemeManager sharedTheme]headerFontWithSize:15.0]];
[textLabel setTextColor:[[AXThemeManager sharedTheme]highlightColor]];
[textLabel setText:@"SECTION TITLE"];
[textLabel setBackgroundColor:[UIColor clearColor]];
UIImageView *backgroundView = [[UIImageView alloc]initWithImage:[AXThemeManager sharedTheme].tableviewSectionHeaderBackgroundImage];
[backgroundView setFrame:view.frame];
[view addSubview:backgroundView];
[view sendSubviewToBack:backgroundView];
[view addSubview:textLabel];
return view;
}
- (float)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 22;
}
- (float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 44;
}
[...]
答案 0 :(得分:10)
我想说这肯定是一个操作系统错误。你正在做什么导致你移动的单元格(使用moveRowAtIndexPath:
)被放置在z顺序的标题单元格的上方(前面)。
我能够在操作系统5和6中重新编写问题,包含已经和没有UITextFields的单元格,以及tableView进出编辑模式(在你的视频中,它处于编辑模式,我注意到了) 。即使您使用标准节标题,也会发生这种情况。
保罗,您在其中一条评论中说道:
我使用装载机严重解决了这个问题,同时“锁定”了桌子 预先形成reloadData
我不确定“使用加载程序并锁定表格”是什么意思,但我确定在reloadData
之后调用moveRowAtIndexPath:
确实解决了问题。这不是你想做的事吗?
[self.tableView moveRowAtIndexPath:indexPath toIndexPath:newPath];
//[self.tableView reloadData];
// per reply by Umka, below, reloadSections works and is lighter than reloadData:
[self reloadSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationNone];
如果你不想这样做,这是另一种对我来说感觉有点笨拙的解决方案,但似乎运行良好(iOS 5 +):
__weak UITableViewCell* blockCell = cell; // so we can refer to cell in the block below without a retain loop warning.
...
cell.onTextEntered = ^(NSString* sText)
{
// move item in my model
NSIndexPath *newPath = [NSIndexPath indexPathForRow:0 inSection:indexPath.section];
[self.itemNames removeObjectAtIndex:indexPath.row];
[self.itemNames insertObject:sText atIndex:0];
// Then you can move cell to back
[self.tableView moveRowAtIndexPath:indexPath toIndexPath:newPath];
[self.tableView sendSubviewToBack:blockCell]; // a little hacky
// OR per @Lombax, move header to front
UIView *sectionView = [self.tableView headerViewForSection:indexPath.section];
[self.tableView bringSubviewToFront:sectionView];
答案 1 :(得分:6)
这是一个错误。 您可以在以下行之后添加快速解决方法:
[self.tableView moveRowAtIndexPath:indexPath toIndexPath:newPath];
这一行:
UIView *sectionView = [self.tableView headerViewForSection:indexPath.section];
[self.tableView bringSubviewToFront:sectionView];
答案 2 :(得分:3)
不是解决方案,但您的代码存在大量问题。谁知道如果你解决它会发生什么;)
(1)在此行之后,您的单元格可能为零:
ListCell * cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
它应该是这样的:
ListCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[ListCell alloc] initWithStyle:style
reuseIdentifier:cellIdentifier] autorelease];
}
(2)两个内存泄漏 - (UIView *)tableView:(UITableView *)aTableView viewForHeaderInSection:(NSInteger)section
- >>修复(当您将标签添加为子视图时,它会获得+1参考)。
UILabel *textLabel = [[[UILabel alloc] initWithFrame:CGRectMake(10, 0, 300, 21)] autorelease];
- >>修复(当您将视图添加为子视图时,它获得+1参考)。
UIImageView *backgroundView = [[[UIImageView alloc]initWithImage:[AXThemeManager sharedTheme].tableviewSectionHeaderBackgroundImage] autorelease];
(3)不是缺陷,但这可能对您有所帮助。尝试使用它而不是[table reloadData]。它允许很好地动画,并不是更新表的硬核方式。我确定它更轻巧。或者尝试寻找其他"更新"方法。如果您不删除示例中的行,则[updateRowsFrom:idxFrom to:idxTo]会有所帮助。
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0]
withRowAnimation:UITableViewRowAnimationAutomatic];
答案 3 :(得分:0)
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
float heightForHeader = 40.0;
if (scrollView.contentOffset.y<=heightForHeader&&scrollView.contentOffset.y>=0) {
scrollView.contentInset = UIEdgeInsetsMake(-scrollView.contentOffset.y, 0, 0, 0);
} else if (scrollView.contentOffset.y>=heightForHeader) {
scrollView.contentInset = UIEdgeInsetsMake(-heightForHeader, 0, 0, 0);
}
}
答案 4 :(得分:0)
我为解决这个问题所做的是在节标题中设置视图的zPosition。
headerView.layer.zPosition = 1000 //just set a bigger number, it will show on top of all other cells.