在 UITableView 中使用插入行
Posted
技术标签:
【中文标题】在 UITableView 中使用插入行【英文标题】:Using insert rows in a UITableView 【发布时间】:2010-12-01 01:13:08 【问题描述】:我希望我的 UITableView 的行为类似于联系人编辑器中的表格,即用户应该点击编辑并且“添加新类别”行应该出现在每个部分的底部。
我正在使用下面的代码来执行此操作,但问题是没有像联系人中那样的平滑过渡。相反,新行突然出现。如何获取动画?
另外,我如何响应点击“添加新类别”行?在我当前的实现中,该行不可点击。
当用户开始编辑时我需要重新加载数据吗?我这样做是因为否则永远不会绘制插入行。
谢谢。
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
[super setEditing:editing animated:animated];
[self.tableView setEditing:editing animated:animated];
[tableView reloadData];
- (NSInteger)tableView:(UITableView *)_tableView numberOfRowsInSection:(NSInteger)section
// ...
if( self.tableView.editing )
return 1 + rowCount;
- (UITableViewCell *)tableView:(UITableView *)_tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
// .....
NSArray* items = ...;
if( indexPath.row >= [items count] )
cell.textLabel.text = @"add new category";
// ...
return cell;
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
NSArray* items = ...;
if( indexPath.row == [items count] )
return UITableViewCellEditingStyleInsert;
return UITableViewCellEditingStyleDelete;
【问题讨论】:
这非常有帮助(连同下面的答案)。只有一点点不一致——与tableView:cellForRowAtIndexPath:
中的行数比较使用>=
,而tableView:editingStyleForRowAtIndexPath:
中的行数使用==
。没什么大不了的,但它们之间应该保持一致。 >=
将涵盖插入行的任何意外双重添加,而 ==
将通过为可能导致这种情况的任何代码错误抛出异常来提供帮助。
【参考方案1】:
响应对行的点击可以在didSelectRowAtIndexPath
方法中完成,对于indexPath.row == [items count]
。对于动画,我建议看一下here,insertRowsAtIndexPaths:withRowAnimation:
方法。有一个关于如何使用它的帖子here。
【讨论】:
【参考方案2】:我错过了一件事。在 setEditing: 中,我不应该调用 reloadData:
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
[super setEditing:editing animated:animated];
[self.tableView setEditing:editing animated:animated]; // not needed if super is a UITableViewController
NSMutableArray* paths = [[NSMutableArray alloc] init];
// fill paths of insertion rows here
if( editing )
[self.tableView insertRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationBottom];
else
[self.tableView deleteRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationBottom];
[paths release];
【讨论】:
谢谢比尔,这对我很有用。我花了几个小时在类似的代码中胡思乱想,但无法完全正确。这带来了不可估量的帮助。 那么 commitEditingStyle: forRowAtIndexPath 呢? Apple 文档说 setEditing 在表格视图第一次进入编辑模式时被调用......你怎么知道此时要插入/删除哪些行? 我不明白你的问题 我认为在滑动单行时会调用 -setEditing:animated: 方法。在这种情况下,您不想插入带有“+”按钮的行。 (也许这就是 shim 的意思?)【参考方案3】:突出显示的解决方案的一个不良副作用是,当用户只滑动一行时,也会插入“添加”行(前提是启用了滑动)。下面的代码解决了这个难题:
// Assuming swipeMode is a BOOL property in the class extension.
- (void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath
// Invoked only when swiping, not when pressing the Edit button.
self.swipeMode = YES;
- (void)tableView:(UITableView *)tableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath
self.swipeMode = NO;
您的代码需要稍作改动:
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
[super setEditing:editing animated:animated];
[self.tableView setEditing:editing animated:animated]; // not needed if super is a UITableViewController
if (!self.swipeMode)
NSMutableArray* paths = [[NSMutableArray alloc] init];
// fill paths of insertion rows here
if( editing )
[self.tableView insertRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationBottom];
else
[self.tableView deleteRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationBottom];
[paths release];
【讨论】:
以上是关于在 UITableView 中使用插入行的主要内容,如果未能解决你的问题,请参考以下文章
iOS 9 UITableView分隔符插入(显着的左边距)