iOS Programming 学习笔记 - 04 UITableView编辑模式

来源:互联网 发布:利他林代购淘宝 编辑:程序博客网 时间:2024/06/07 06:26

之前一节我们创建了显示BNRItem的UITableView,接下来我们对Homepwner进行扩展,让用户可以对表格进行插入、删除和移动操作。完成之后的效果如下:


1. 编辑模式

UITableView有一个编辑模式,进入编辑模式后,用户就可以添加,删除和移动行。接下来我们创建一个table的header view,在这个view上创建一个编辑按钮和新建行按钮。

修改BNRItemsViewController.m,添加headerView的outlet

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

创建空的action,edit和new:

- (IBAction)addNewItem:(id)sender{    }- (IBAction)toggleEditMode:(id)sender{    }

接下来,创建XIB文件-HeaderView.xib,将file owner改为BNRItemsViewController类。


添加一个UIView到canvas中,并入下图所示设置这个view的属性,这样我们就可以修改view的size了:

修改完毕后将两个UIButton添加到headerview中并连接outlet和相应的action:

实现headerView的get方法,通过NSBundle加载xib文件:

- (UIView *)headerView{    if (!_headerView)    {        // Load HeaderView.xib        [[NSBundle mainBundle] loadNibNamed:@"HeaderView" owner:self options:nil];    }        return _headerView;}
在viewDidLoad中创建headerview并设置为table的header:

- (void)viewDidLoad {    [super viewDidLoad];        [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"UITableViewCell"];        UIView *header = self.headerView;    [self.tableView setTableHeaderView:header];}
程序执行效果如下:

接下来,我们实现toggleEditingMode方法。

- (IBAction)toggleEditMode:(id)sender{    // If you are currently in editing mode    if (self.isEditing)    {        // Change text of the buttong to inform user of state        [sender setTitle:@"Edit" forState:UIControlStateNormal];                // Turn off editing mode        [self setEditing:NO animated:YES];    }    else    {        [sender setTitle:@"Done" forState:UIControlStateNormal];                [self setEditing:YES animated:YES];    }}
编译运行,点击edit效果如下:


2. 添加行

这里我们实现addNewItem方法来为table添加行,通过BNRItemStore创建一个新的item,查询这个item在store中的位置,通过这个位置获取indexPath,最后将这个添加新的行到table中。

- (IBAction)addNewItem:(id)sender{    // Create a new BNRItem and add it to the store    BNRItem *newItem = [[BNRItemStore sharedStore] createItem];        // Figure out where that item is in the array    NSInteger lastRow = [[[BNRItemStore sharedStore] allItems] indexOfObject:newItem];        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:lastRow inSection:0];        // Insert this new row into the table    [self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationTop];}

3. 删除行

在编辑模式下,通过红色按钮可以删除行。删除行有两件事要做,一是将这行从UITableView中删除,二是将对应BNRItem从store中删除。

修改BNRItemStore.h,声明removeItem方法:

#import <Foundation/Foundation.h>@class BNRItem;@interface BNRItemStore : NSObject@property (nonatomic, readonly) NSArray *allItems;+ (instancetype)sharedStore;- (BNRItem *)createItem;- (void)removeItem:(BNRItem *)item;@end
实现该方法:

- (void)removeItem:(BNRItem *)item{    [self.privateItems removeObjectIdenticalTo:item];}
接下来在BNRItemsViewController.m中重载commitEditingStyle方法,实现删除行操作:

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{    // If the table view is asking to commit a delete command    if (editingStyle == UITableViewCellEditingStyleDelete)    {        NSArray *items = [[BNRItemStore sharedStore] allItems];        BNRItem *item = items[indexPath.row];                [[BNRItemStore sharedStore] removeItem:item];                // Also remove that row from the table view with an animation        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];    }}

4. 移动行

移动行需要使用UITableViewDataSource协议的另一个方法-tableView:moveRowAtIndexPath:toIndexPath:

首先在BNRItemStore中声明和实现moveItemAtIndex方法:

- (void)moveItemAtIndex:(NSUInteger)fromIndex                toIndex:(NSUInteger)toIndex;
- (void)moveItemAtIndex:(NSUInteger)fromIndex toIndex:(NSUInteger)toIndex{    if (fromIndex == toIndex)    {        return;    }        // Get pointer to object being moved so you can reinsert it    BNRItem *item = self.privateItems[fromIndex];        // Remove item from array    [self.privateItems removeObjectAtIndex:fromIndex];        // Insert item in array at new location    [self.privateItems insertObject:item atIndex:toIndex];}

接下来重载tableView:moveRowAtIndexPath:toIndexPath:方法来更新store:

- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath{    [[BNRItemStore sharedStore] moveItemAtIndex:sourceIndexPath.row toIndex:destinationIndexPath.row];}
编译运行,进入编辑模式即可对行进行位置移动操作。这里比较有意思的是,之前进入编辑模式,并没有行移动控制键在行的最右侧,当我们实现moveRowAtIndexPath方法后,在进入编辑模式iOS的UITableView会自动生成行移动按钮。








0 0