单元格显示在部分标题的顶部

我有一个UITableView自定义单元格和自定义标题。 在编辑时移动一个单元格时,会popup到标题视图。 我怎样才能保持在所有单元格顶部的标题视图?

该应用程序使用故事板,以防有所作为。

这是怎么样? 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; } [...] 

好消息! 我能够以两种不同的方式修复/解决你的问题(见下文)。

我会说这肯定是一个操作系统的错误。 你正在做什么导致你已经移动的单元格(使用moveRowAtIndexPath:被放置在标题单元格的上面(在前面)z顺序。

我能够在操作系统5和6,与单元格,没有UITextFields,并与tableView进出编辑模式(在你的video,它是在编辑模式,我注意到)的问题,repro的问题。 即使您使用标准节标题,也会发生这种情况。

保罗 ,你在你的一个评论中说:

我用一个加载器解决了这个问题,并在执行reloadData的同时“locking”表

我不知道你是什么意思的“使用加载器和locking表”,但我确实调用moveRowAtIndexPath:后调用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]; 

如果你不想这样做,这里是另一个解决scheme,我觉得有点哈克,但似乎工作得很好(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]; 

这是一个错误。 您可以通过在该行之后添加来快速解决该问题:

 [self.tableView moveRowAtIndexPath:indexPath toIndexPath:newPath]; 

这行:

 UIView *sectionView = [self.tableView headerViewForSection:indexPath.section]; [self.tableView bringSubviewToFront:sectionView]; 

不是一个解决scheme,但你的代码有一些问题。 谁知道如果你修好了会发生什么;)

(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)部分

– >>修正(当你添加标签作为子视图获得+1参考)。

 UILabel *textLabel = [[[UILabel alloc] initWithFrame:CGRectMake(10, 0, 300, 21)] autorelease]; 

– >>修正(当你添加视图作为子视图时获得+1 ref)。

 UIImageView *backgroundView = [[[UIImageView alloc]initWithImage:[AXThemeManager sharedTheme].tableviewSectionHeaderBackgroundImage] autorelease]; 

(3)不是一个缺陷,但这可能会帮助你。 尝试使用这个而不是[table reloadData]。 它允许很好的animation,而不是更新表的核心方式。 我相信它更轻量。 或者尝试寻找其他“更新”方法。 鉴于你不删除在你的例子中的行,像[updateRowsFrom:idxFrom到:idxTo]将有所帮助。

 [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationAutomatic]; 
 - (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); } } 

我做了什么来解决这个问题是在部分标题中设置视图的zPosition。

 headerView.layer.zPosition = 1000 //just set a bigger number, it will show on top of all other cells.