UITableView的编辑操作

  继续上篇UITableView和UITableViewController

打开BNRItemsViewController.m,在类扩展中添加如下属性:

@property (nonatomic, strong) IBOutlet UIView *headerView;

  在XIB文件中,headerView是最顶层的对象。该视图包含的对象要使用weak引用。

并在implementation部分增加如下方法:

 - (IBAction)addNewItem:(id)sender {

 }

 - (IBAction)toggleEditingMode:(id)sender {

 }

  File -> New ->File... -> iOS ->User Interface -> Empty,命名为:HeaderView。

选中刚创建的HeaderView.xib,选中File's Owner,Identity Inspector -> Custom Class 中的class改为BNRItemsViewController。

在canvas中拖入UIView视图,将其Attributes Inspector的Simulated Metrics设置为如下:

UITableView的编辑操作

为将该UIView对象完全透明的,选择Attributes Inspector -> View -> Background -> Clear Color。

  调整UIView的大小,再往该视图中添加两个按钮,如下所示:

UITableView的编辑操作

  按住Control键,点击File's Owner,拖到UIView中,与headerView实例变量建立连接。将Edit按钮与toggleEditingMode:建立连接,将New与addNewItem:建立连接。

  我们需要手动添加如下代码,让BNRItemsViewController加载XIB文件:

 - (UIView *)headerView {
// 如果还没加载headerView
if (!_headerView) {
// 加载HeaderView.xib
[[NSBundle mainBundle] loadNibNamed:@"HeaderView" owner:self options:nil];
}
return _headerView;
}

  通过发送loadNibNamed:owner:options:方法给应用程序的bundle,任何对象都能加载一个XIB文件。

  现在需要告诉表视图关于头视图的信息,修改viewDidLoad方法如下:

 - (void)viewDidLoad {
[super viewDidLoad];
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"UITableViewCell"]; UIView *header = self.headerView;
[self.tableView setTableHeaderView:header];
}

  运行程序,结果为:

UITableView的编辑操作

  修改toggleEditingMode:方法如下:

 - (IBAction)toggleEditingMode:(id)sender {
// 现在是否处于编辑模式
if (self.isEditing) {
// 改变按钮的文本为Edit,并关闭编辑模式
[sender setTitle:@"Edit" forState:UIControlStateNormal];
[self setEditing:NO animated:YES];
} else {
// 改变按钮的文本为Done,并开启编辑模式
[sender setTitle:@"Done" forState:UIControlStateNormal];
[self setEditing:YES animated:YES];
}
}

  运行程序,结果为:

UITableView的编辑操作

  为了实现点击New按钮可添加新项目,修改addNewItem:方法如下:

 - (IBAction)addNewItem:(id)sender {
// 创建一个新的BNRItem,并将其添加到sharedStore中
BNRItem *newItem = [[BNRItemStore sharedStore] createItem];
// 获取newItem在数组中的位置
NSInteger lastRow = [[[BNRItemStore sharedStore] allItems] indexOfObject:newItem];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:lastRow inSection:];
// 将newItem插入表中
[self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationTop];
}

  UITableView的dataSource决定表视图显示的行数,要确保UITableView和dataSource的行数要一致。

  当删除一个cell的时候,1)要从UITableView中删除该行;2)将BNRItem从BNRItemStore中删除。

在BNRItemStore.h中,声明新方法如下:

- (void)removeItem:(BNRItem *)item;

在BNRItemStore.m中,实现removeItem:方法如下:

- (void)removeItem:(BNRItem *)item {
[self.privateItems removeObjectIdenticalTo:item];
}

删除行时,tableView:commitEditingStyle:forRowAtIndexPath:将被发送给dataSource,实现该方法:

 - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
// 如果表视图要求进行删除命令
if (editingStyle == UITableViewCellEditingStyleDelete) {
NSArray *items = [[BNRItemStore sharedStore] allItems];
BNRItem *item = items[indexPath.row];
[[BNRItemStore sharedStore] removeItem:item];
// 将该行从表视图中删除,并附带动画
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}

移动行:

在BNRitem.h中添加一个方法,用来改变allItems中items的顺序,方法如下:

- (void)moveItemAtIndex:(NSUInteger)fromIndex toIndex:(NSUInteger)toIndex;

在BNRitem.m的实现代码为:

- (void)moveItemAtIndex:(NSUInteger)fromIndex toIndex:(NSUInteger)toIndex {
if (fromIndex == toIndex) {
return;
}
BNRItem *item = self.privateItems[fromIndex];
[self.privateItems removeObjectAtIndex:fromIndex];
[self.privateItems insertObject:item atIndex:toIndex];
}

tableView:moveRowAtIndexPath:toIndexPath:用于改变一个UITableView中的行。

在BNRItemsViewController.m中添加如下代码:

- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath {
[[BNRItemStore sharedStore] moveItemAtIndex:sourceIndexPath.row toIndex:destinationIndexPath.row];
}

运行结果如下:

UITableView的编辑操作

程序代码:https://github.com/wjq332608421/learngit/blob/master/Homepwner.zip

上一篇:让Myeclipse自动生成的get set方法 自动加上文本注释,并且注释内容包含字段中我们加的文档注释


下一篇:如何自动在Eclipse里对指定类或接口生成要覆盖的方法?