zoukankan      html  css  js  c++  java
  • iOS 编辑UITableView(根据iOS编程编写)

      上个项目我们完成了 JXHomepwner 简单的应用展示,项目地址。本节我们需要在上节项目基础上,增加一些响应用户操作。包括添加,删除和移动表格。

    • 编辑模式

      UITableView 有一个名为  editing 的属性,如果将其设置为  YES UITableView 就会进入编辑模式。在编辑模式下,用户可以管理 UITableView 中的表格行,我们可以添加、删除和移动等操作。但是编辑模式没有听过修改行的内容的功能。

      首先要更新界面,使用户可以将 UITableView 对象设置为编辑模式。示例程序是为 UITableView 对象的 表头视图 增加一个按钮,然后通过按钮使  UITableView 对象进入或者退出编辑模式。表头视图是指 UITableView 对象可以在其表格上方显示特定视图,适合放置针对某个表格段或者整张表格的标题和控件。表头视图可以是任意的 UIView 对象。

      表头视图有两种,分别针对表格段和表格。类似的,还有 表尾视图 也具有表格段和表格两种。

      接下来创建一个针对表格的表头视图。这个表头视图包含两个 UIButton 对象,其中一个负责切换 UITableView 对象的编辑模式,另一个负责创建新的 JXItem 对象并加入 UITableView 对象。可以使用代码,也可以使用 XIB 方式来创建。

    #import "JXItemsViewController.h"
    #import "JXItem.h"
    #import "JXItemStore.h"
    
    @interface JXItemsViewController ()
    /** 头部视图 */
    @property (nonatomic,weak) UIView * headerView;
    /** 编辑按钮 */
    @property (nonatomic,strong) UIButton * editButton;
    
    @end
    
    @implementation JXItemsViewController
    
    - (instancetype)init {
        // 调用父类的指定初始化方法
        self = [super initWithStyle:UITableViewStylePlain];
        if (self) {
            for (NSInteger i=0; i<15; i++) {
                [[JXItemStore sharedStore] createItem];
            }
        }
        return self;
    }
    
    - (instancetype)initWithStyle:(UITableViewStyle)style {
        return [self init];
    }
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        // 向控制器注册
        [self.tableView registerClass:[UITableViewCell class]
               forCellReuseIdentifier:@"UITableViewCell"];
    
        
        // 加载头视图
        [self headerView];
    }
    
    #pragma mark - Table view data source
    
    
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
        return [[[JXItemStore sharedStore] allItem] count];
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        // 创建 UITableViewCell 对象,风格使用默认风格
        UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"UITableViewCell"
                                                                 forIndexPath:indexPath];
        // 获取 allItem 的第 n 个 JXItem 对象
        // 然后将该 JXItem 对象的描述信息赋值给 UITableViewCell 对象的 textLabel
        // 这里的 n 是该 UITableViewCell 对象所对应的表格索引
        NSArray * items = [[JXItemStore sharedStore] allItem];
        JXItem * item = items[indexPath.row];
        
        cell.textLabel.text = [item description];
        return cell;
    }
    
    #pragma mark - 懒加载
    - (UIView *)headerView{
        if (_headerView == nil) {
            UIView * headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 50)];
            // 设置头部视图
            self.tableView.tableHeaderView = headerView;
            headerView.backgroundColor = [UIColor cyanColor];
            [headerView addSubview:self.editButton];
            _headerView = headerView;
        }
        return _headerView;
    }
    
    - (UIButton *)editButton{
        if (_editButton == nil) {
            _editButton = [UIButton buttonWithType:UIButtonTypeCustom];
            _editButton.frame = CGRectMake(0, 0, self.view.bounds.size.width / 2, 50);
            [_editButton setTitle:@"Edit" forState:UIControlStateNormal];
            _editButton.backgroundColor = [UIColor greenColor];
            [_editButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
            [_editButton addTarget:self action:@selector(editClick:) forControlEvents:UIControlEventTouchDown];
        }
        return _editButton;
    }
    
    #pragma mark - 点击事件
    - (void)editClick:(UIButton *)sender {
        if (self.isEditing) { // 如果是编辑状态,取消编辑
            
            // 更改文字
            [sender setTitle:@"Edit" forState:UIControlStateNormal];
            
            // 取消编辑
            [self setEditing:NO animated:YES];
        } else {
            
            // 更改文字
            [sender setTitle:@"Done" forState:UIControlStateNormal];
            
            // 开始编辑
            [self setEditing:YES animated:YES];
        }
    }
    @end

      构建并运行结果

    • 增加行

      通常有两种方式可以在运行时为 UITableView 对象增加行。

      * 在表视图上方放置添加按钮。如果数据的字段比较多的话,就需要显示一个用于输入的详细视图,就可以使用这种方式。例如,在iOS自带通讯录中,点击添加按钮。

      * 在 UITableViewCell 对象左边显示一个绿色加号按钮。在为数据添加一个新字段时可以使用这种方式。在联系人应用中为联系人添加生日。

     本节采用另一种方式:在  headView 中放置一个标题为 New 的按钮。当用户点击这个按钮,添加一行新数据。

    #import "JXItemsViewController.h"
    #import "JXItem.h"
    #import "JXItemStore.h"
    
    @interface JXItemsViewController ()
    /** 头部视图 */
    @property (nonatomic,weak) UIView * headerView;
    /** 编辑按钮 */
    @property (nonatomic,strong) UIButton * editButton;
    
    /** 增加按钮 */
    @property (nonatomic,strong) UIButton * addButton;
    
    @end
    
    @implementation JXItemsViewController
    
    - (instancetype)init {
        // 调用父类的指定初始化方法
        self = [super initWithStyle:UITableViewStylePlain];
        if (self) {
            for (NSInteger i=0; i<15; i++) {
                [[JXItemStore sharedStore] createItem];
            }
        }
        return self;
    }
    
    - (instancetype)initWithStyle:(UITableViewStyle)style {
        return [self init];
    }
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        // 向控制器注册
        [self.tableView registerClass:[UITableViewCell class]
               forCellReuseIdentifier:@"UITableViewCell"];
    
        
        // 加载头视图
        [self headerView];
    }
    
    #pragma mark - Table view data source
    
    
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
        return [[[JXItemStore sharedStore] allItem] count];
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        // 创建 UITableViewCell 对象,风格使用默认风格
        UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"UITableViewCell"
                                                                 forIndexPath:indexPath];
        // 获取 allItem 的第 n 个 JXItem 对象
        // 然后将该 JXItem 对象的描述信息赋值给 UITableViewCell 对象的 textLabel
        // 这里的 n 是该 UITableViewCell 对象所对应的表格索引
        NSArray * items = [[JXItemStore sharedStore] allItem];
        JXItem * item = items[indexPath.row];
        
        cell.textLabel.text = [item description];
        return cell;
    }
    
    #pragma mark - 懒加载
    - (UIView *)headerView{
        if (_headerView == nil) {
            UIView * headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 50)];
            // 设置头部视图
            self.tableView.tableHeaderView = headerView;
            headerView.backgroundColor = [UIColor cyanColor];
            [headerView addSubview:self.editButton];
            [headerView addSubview:self.addButton];
            _headerView = headerView;
        }
        return _headerView;
    }
    
    - (UIButton *)editButton{
        if (_editButton == nil) {
            _editButton = [UIButton buttonWithType:UIButtonTypeCustom];
            _editButton.frame = CGRectMake(0, 0, self.view.bounds.size.width / 2, 50);
            [_editButton setTitle:@"Edit" forState:UIControlStateNormal];
            _editButton.backgroundColor = [UIColor greenColor];
            [_editButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
            [_editButton addTarget:self action:@selector(editClick:) forControlEvents:UIControlEventTouchDown];
        }
        return _editButton;
    }
    
    - (UIButton *)addButton{
        if (_addButton == nil) {
            UIButton * addButton = [UIButton buttonWithType:UIButtonTypeCustom];
            addButton.frame = CGRectMake(self.view.bounds.size.width / 2, 0, self.view.bounds.size.width / 2, 50);
            [addButton setTitle:@"Add" forState:UIControlStateNormal];
            addButton.backgroundColor = [UIColor blueColor];
            [addButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
            [addButton addTarget:self action:@selector(addClick:) forControlEvents:UIControlEventTouchDown];
            _addButton = addButton;
        }
        return _addButton;
    }
    
    #pragma mark - 点击事件
    - (void)editClick:(UIButton *)sender {
        if (self.isEditing) { // 如果是编辑状态,取消编辑
            
            // 更改文字
            [sender setTitle:@"Edit" forState:UIControlStateNormal];
            
            // 取消编辑
            [self setEditing:NO animated:YES];
        } else {
            
            // 更改文字
            [sender setTitle:@"Done" forState:UIControlStateNormal];
            
            // 开始编辑
            [self setEditing:YES animated:YES];
        }
    }
    
    /**
     *  添加表格时,必须保证 UITableView 对象当前显示的行数与数据源的提供的行数相同。
     *  所以,在添加之前,必须先创建一个新的 JXItem 对象并加入到 JXItemStore 中
     *
     *  @param sender 按钮
     */
    - (void)addClick:(UIButton *)sender {
        
        // 创建新的 JXItem 对象,并加入到 JXItemStore 中
        JXItem * newItem = [[JXItemStore sharedStore] createItem];
        
        // 获取新的对象在 allItem 数组中的索引
        NSInteger lastRow = [[[JXItemStore sharedStore] allItem] indexOfObject:newItem];
        NSIndexPath * indexPath = [NSIndexPath indexPathForRow:lastRow inSection:0];
        
        // 将新航插入 UITableView 对象
        [self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationTop];
    }
    @end

      构建并运行

    • 删除行

      在编辑模式下,UITableViewCell 对象可能是会显示中间有个减号的红色圆圈。这个红色圆圈是删除行控件,按下删除控件就可以删除其所属的那个表格行。但是目前我们的应用按下不会有任何操作。  

      要删除 JXHomepwner 中的某个表格行,就必须执行两步:1.从UITableView 对象删除指定的 UITableViewCell 对象。2.找到和需要删除的 UITableViewCell 对象对应的 JXItem 对象,也将其从 JXItemStore 中删除。为了完成第二步,我们必须在 JXItemStore 中实现新的方法。

    #import <Foundation/Foundation.h>
    
    @class JXItem;
    @interface JXItemStore : NSObject
    
    /** 存放 JXItem 对象数组 */
    @property (nonatomic,readonly) NSArray * allItem;
    
    // 注意,这是一个类方法,前缀是+
    + (instancetype)sharedStore;
    
    - (JXItem *)createItem;
    
    /**
     *  删除对象
     *
     *  @param item 需要删除的对象
     */
    - (void)removeItem:(JXItem *)item;
    
    @end
    #import "JXItemStore.h"
    #import "JXItem.h"
    
    @interface JXItemStore ()
    
    /** 可变数组,用来操作 JXItem 对象 */
    @property (nonatomic,strong) NSMutableArray * privateItems;
    
    @end
    
    @implementation JXItemStore
    
    // 单粒对象
    + (instancetype)sharedStore {
        static JXItemStore * sharedStore = nil;
        
        // 判断是否需要创建一个 sharedStore 对象
        if (!sharedStore) {
            sharedStore = [[self alloc] init];
        }
        return sharedStore;
    }
    - (NSArray *)allItem {
        return [self.privateItems copy];
    }
    
    - (JXItem *)createItem {
        JXItem * item = [JXItem randomItem];
        [self.privateItems addObject:item];
        return item;
    }
    
    
    /**
     *  还可以调用 [self.privateItems removeObject:item]
     *  [self.privateItems removeObjectIdenticalTo:item] 与上面的方法的区别就是:上面的方法会枚举数组,向每一个数组发送 isEqual: 消息。
     *  isEqual: 的作用是判断当前对象和传入对象所包含的数据是否相等。可能会复写 这个方法。
     *  removeObjectIdenticalTo: 方法不会比较对象所包含的数据,只会比较指向对象的指针
     *
     *  @param item 需要删除的对象
     */
    - (void)removeItem:(JXItem *)item {
        
        [self.privateItems removeObjectIdenticalTo:item];
        
    }
    #pragma mark - 懒加载
    - (NSMutableArray *)privateItems{
        if (_privateItems == nil) {
            _privateItems = [[NSMutableArray alloc] init];
        }
        return _privateItems;
    }
    @end

      接下来为  JXItemsViewController 实现 

    - (void)tableView:(UITableView *)tableView
    commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
    forRowAtIndexPath:(NSIndexPath *)indexPath 

      这个方法是  UITableViewDataSource 协议所声明的方法之一。当 UITableView 对象在向其数据源发送这个消息的时候,会传入三个实参。第一个参数是发送该消息的 UITableView 对象。第二个实参是 UITableViewCellEditingStyle 类型的常量(删除表格行时,传入的是UITableViewCellEditingStyleDelete)。第三个实参是一个 NSIndexPath 对象,其中包含相应表格行所在的表格段索引和行索引。

      

    #import "JXItemsViewController.h"
    #import "JXItem.h"
    #import "JXItemStore.h"
    
    @interface JXItemsViewController ()
    /** 头部视图 */
    @property (nonatomic,weak) UIView * headerView;
    /** 编辑按钮 */
    @property (nonatomic,strong) UIButton * editButton;
    
    /** 增加按钮 */
    @property (nonatomic,strong) UIButton * addButton;
    
    @end
    
    @implementation JXItemsViewController
    
    - (instancetype)init {
        // 调用父类的指定初始化方法
        self = [super initWithStyle:UITableViewStylePlain];
        if (self) {
            for (NSInteger i=0; i<15; i++) {
                [[JXItemStore sharedStore] createItem];
            }
        }
        return self;
    }
    
    - (instancetype)initWithStyle:(UITableViewStyle)style {
        return [self init];
    }
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        // 向控制器注册
        [self.tableView registerClass:[UITableViewCell class]
               forCellReuseIdentifier:@"UITableViewCell"];
    
        
        // 加载头视图
        [self headerView];
    }
    
    #pragma mark - Table view data source
    
    
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
        return [[[JXItemStore sharedStore] allItem] count];
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        // 创建 UITableViewCell 对象,风格使用默认风格
        UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"UITableViewCell"
                                                                 forIndexPath:indexPath];
        // 获取 allItem 的第 n 个 JXItem 对象
        // 然后将该 JXItem 对象的描述信息赋值给 UITableViewCell 对象的 textLabel
        // 这里的 n 是该 UITableViewCell 对象所对应的表格索引
        NSArray * items = [[JXItemStore sharedStore] allItem];
        JXItem * item = items[indexPath.row];
        
        cell.textLabel.text = [item description];
        return cell;
    }
    
    /**
     *  删除行
     *
     *  @param tableView    对象
     *  @param editingStyle 操作
     *  @param indexPath    操作的行数
     */
    - (void)tableView:(UITableView *)tableView
    commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
    forRowAtIndexPath:(NSIndexPath *)indexPath {
        
        // 如果tableView请求的是删除对象
        if (editingStyle == UITableViewCellEditingStyleDelete) {
            
            // 取出需要删除的对象
            NSArray * items = [[JXItemStore sharedStore] allItem];
            JXItem * item = items[indexPath.row];
            
            // 删除对象
            [[JXItemStore sharedStore] removeItem:item];
            
            // 刷新表格
            [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
        }
        
    }
    #pragma mark - 懒加载
    - (UIView *)headerView{
        if (_headerView == nil) {
            UIView * headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 50)];
            // 设置头部视图
            self.tableView.tableHeaderView = headerView;
            headerView.backgroundColor = [UIColor cyanColor];
            [headerView addSubview:self.editButton];
            [headerView addSubview:self.addButton];
            _headerView = headerView;
        }
        return _headerView;
    }
    
    - (UIButton *)editButton{
        if (_editButton == nil) {
            _editButton = [UIButton buttonWithType:UIButtonTypeCustom];
            _editButton.frame = CGRectMake(0, 0, self.view.bounds.size.width / 2, 50);
            [_editButton setTitle:@"Edit" forState:UIControlStateNormal];
            _editButton.backgroundColor = [UIColor greenColor];
            [_editButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
            [_editButton addTarget:self action:@selector(editClick:) forControlEvents:UIControlEventTouchDown];
        }
        return _editButton;
    }
    
    - (UIButton *)addButton{
        if (_addButton == nil) {
            UIButton * addButton = [UIButton buttonWithType:UIButtonTypeCustom];
            addButton.frame = CGRectMake(self.view.bounds.size.width / 2, 0, self.view.bounds.size.width / 2, 50);
            [addButton setTitle:@"Add" forState:UIControlStateNormal];
            addButton.backgroundColor = [UIColor blueColor];
            [addButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
            [addButton addTarget:self action:@selector(addClick:) forControlEvents:UIControlEventTouchDown];
            _addButton = addButton;
        }
        return _addButton;
    }
    
    #pragma mark - 点击事件
    - (void)editClick:(UIButton *)sender {
        if (self.isEditing) { // 如果是编辑状态,取消编辑
            
            // 更改文字
            [sender setTitle:@"Edit" forState:UIControlStateNormal];
            
            // 取消编辑
            [self setEditing:NO animated:YES];
        } else {
            
            // 更改文字
            [sender setTitle:@"Done" forState:UIControlStateNormal];
            
            // 开始编辑
            [self setEditing:YES animated:YES];
        }
    }
    
    /**
     *  添加表格时,必须保证 UITableView 对象当前显示的行数与数据源的提供的行数相同。
     *  所以,在添加之前,必须先创建一个新的 JXItem 对象并加入到 JXItemStore 中
     *
     *  @param sender 按钮
     */
    - (void)addClick:(UIButton *)sender {
        
        // 创建新的 JXItem 对象,并加入到 JXItemStore 中
        JXItem * newItem = [[JXItemStore sharedStore] createItem];
        
        // 获取新的对象在 allItem 数组中的索引
        NSInteger lastRow = [[[JXItemStore sharedStore] allItem] indexOfObject:newItem];
        NSIndexPath * indexPath = [NSIndexPath indexPathForRow:lastRow inSection:0];
        
        // 将新航插入 UITableView 对象
        [self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationTop];
    }
    @end

      接下来,继续调用数据源代理的另一个方法

    - (void)tableView:(UITableView *)tableView
    moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath
          toIndexPath:(NSIndexPath *)destinationIndexPath 

      是当在编辑模式下,会在每个表格行的右侧显示一个换位控件,按住拖动,可以将相应的表格行移动到手指拖动的位置。对象在向其数据源发送这个消息的时候,同样会传入三个实参。第一个参数是发送该消息的 UITableView 对象。第二个实参是 NSIndexPath 对象是表格原位置。第三个实参是一个 NSIndexPath 对象是目的位置

    #import <Foundation/Foundation.h>
    
    @class JXItem;
    @interface JXItemStore : NSObject
    
    /** 存放 JXItem 对象数组 */
    @property (nonatomic,readonly) NSArray * allItem;
    
    // 注意,这是一个类方法,前缀是+
    + (instancetype)sharedStore;
    
    - (JXItem *)createItem;
    
    /**
     *  删除对象
     *
     *  @param item 需要删除的对象
     */
    - (void)removeItem:(JXItem *)item;
    
    /**
     *  移动对象
     *
     *  @param fromIndex 移动对象的起始位置
     *  @param toIndex   移动后的位置
     */
    - (void)moveItemAtIndex:(NSInteger)fromIndex
                    toIndex:(NSInteger)toIndex;
    
    @end
    #import "JXItemStore.h"
    #import "JXItem.h"
    
    @interface JXItemStore ()
    
    /** 可变数组,用来操作 JXItem 对象 */
    @property (nonatomic,strong) NSMutableArray * privateItems;
    
    @end
    
    @implementation JXItemStore
    
    // 单粒对象
    + (instancetype)sharedStore {
        static JXItemStore * sharedStore = nil;
        
        // 判断是否需要创建一个 sharedStore 对象
        if (!sharedStore) {
            sharedStore = [[self alloc] init];
        }
        return sharedStore;
    }
    - (NSArray *)allItem {
        return [self.privateItems copy];
    }
    
    - (JXItem *)createItem {
        JXItem * item = [JXItem randomItem];
        [self.privateItems addObject:item];
        return item;
    }
    
    
    /**
     *  还可以调用 [self.privateItems removeObject:item]
     *  [self.privateItems removeObjectIdenticalTo:item] 与上面的方法的区别就是:上面的方法会枚举数组,向每一个数组发送 isEqual: 消息。
     *  isEqual: 的作用是判断当前对象和传入对象所包含的数据是否相等。可能会复写 这个方法。
     *  removeObjectIdenticalTo: 方法不会比较对象所包含的数据,只会比较指向对象的指针
     *
     *  @param item 需要删除的对象
     */
    - (void)removeItem:(JXItem *)item {
        
        [self.privateItems removeObjectIdenticalTo:item];
        
    }
    
    
    - (void)moveItemAtIndex:(NSInteger)fromIndex toIndex:(NSInteger)toIndex {
        
        // 如果起始位置和最终位置相同,则不懂
        if (fromIndex == toIndex) return;
        
        // 需要移动的对象的指针
        JXItem * item = self.privateItems[fromIndex];
        
        // 将 item 从 allItem 数组中移除
        [self.privateItems removeObjectAtIndex:fromIndex];
        
        // 根据新的索引位置,将item 插入到allItem 数组中
        [self.privateItems insertObject:item atIndex:toIndex];
    }
    
    #pragma mark - 懒加载
    - (NSMutableArray *)privateItems{
        if (_privateItems == nil) {
            _privateItems = [[NSMutableArray alloc] init];
        }
        return _privateItems;
    }
    @end
    #import "JXItemsViewController.h"
    #import "JXItem.h"
    #import "JXItemStore.h"
    
    @interface JXItemsViewController ()
    /** 头部视图 */
    @property (nonatomic,weak) UIView * headerView;
    /** 编辑按钮 */
    @property (nonatomic,strong) UIButton * editButton;
    
    /** 增加按钮 */
    @property (nonatomic,strong) UIButton * addButton;
    
    @end
    
    @implementation JXItemsViewController
    
    - (instancetype)init {
        // 调用父类的指定初始化方法
        self = [super initWithStyle:UITableViewStylePlain];
        if (self) {
            for (NSInteger i=0; i<15; i++) {
                [[JXItemStore sharedStore] createItem];
            }
        }
        return self;
    }
    
    - (instancetype)initWithStyle:(UITableViewStyle)style {
        return [self init];
    }
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        // 向控制器注册
        [self.tableView registerClass:[UITableViewCell class]
               forCellReuseIdentifier:@"UITableViewCell"];
    
        
        // 加载头视图
        [self headerView];
    }
    
    #pragma mark - Table view data source
    
    
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
        return [[[JXItemStore sharedStore] allItem] count];
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        // 创建 UITableViewCell 对象,风格使用默认风格
        UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"UITableViewCell"
                                                                 forIndexPath:indexPath];
        // 获取 allItem 的第 n 个 JXItem 对象
        // 然后将该 JXItem 对象的描述信息赋值给 UITableViewCell 对象的 textLabel
        // 这里的 n 是该 UITableViewCell 对象所对应的表格索引
        NSArray * items = [[JXItemStore sharedStore] allItem];
        JXItem * item = items[indexPath.row];
        
        cell.textLabel.text = [item description];
        return cell;
    }
    
    /**
     *  删除行
     *
     *  @param tableView    对象
     *  @param editingStyle 操作
     *  @param indexPath    操作的行数
     */
    - (void)tableView:(UITableView *)tableView
    commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
    forRowAtIndexPath:(NSIndexPath *)indexPath {
        
        // 如果tableView请求的是删除对象
        if (editingStyle == UITableViewCellEditingStyleDelete) {
            
            // 取出需要删除的对象
            NSArray * items = [[JXItemStore sharedStore] allItem];
            JXItem * item = items[indexPath.row];
            
            // 删除对象
            [[JXItemStore sharedStore] removeItem:item];
            
            // 刷新表格
            [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
        }
        
    }
    /**
     *  移动行
     *
     *  @param tableView            对象
     *  @param sourceIndexPath      需要移动的行
     *  @param destinationIndexPath 目标行
     */
    - (void)tableView:(UITableView *)tableView
    moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath
          toIndexPath:(NSIndexPath *)destinationIndexPath {
        
        [[JXItemStore sharedStore] moveItemAtIndex:sourceIndexPath.row
                                           toIndex:destinationIndexPath.row];
    }
    
    #pragma mark - 懒加载
    - (UIView *)headerView{
        if (_headerView == nil) {
            UIView * headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 50)];
            // 设置头部视图
            self.tableView.tableHeaderView = headerView;
            headerView.backgroundColor = [UIColor cyanColor];
            [headerView addSubview:self.editButton];
            [headerView addSubview:self.addButton];
            _headerView = headerView;
        }
        return _headerView;
    }
    
    - (UIButton *)editButton{
        if (_editButton == nil) {
            _editButton = [UIButton buttonWithType:UIButtonTypeCustom];
            _editButton.frame = CGRectMake(0, 0, self.view.bounds.size.width / 2, 50);
            [_editButton setTitle:@"Edit" forState:UIControlStateNormal];
            _editButton.backgroundColor = [UIColor greenColor];
            [_editButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
            [_editButton addTarget:self action:@selector(editClick:) forControlEvents:UIControlEventTouchDown];
        }
        return _editButton;
    }
    
    - (UIButton *)addButton{
        if (_addButton == nil) {
            UIButton * addButton = [UIButton buttonWithType:UIButtonTypeCustom];
            addButton.frame = CGRectMake(self.view.bounds.size.width / 2, 0, self.view.bounds.size.width / 2, 50);
            [addButton setTitle:@"Add" forState:UIControlStateNormal];
            addButton.backgroundColor = [UIColor blueColor];
            [addButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
            [addButton addTarget:self action:@selector(addClick:) forControlEvents:UIControlEventTouchDown];
            _addButton = addButton;
        }
        return _addButton;
    }
    
    #pragma mark - 点击事件
    - (void)editClick:(UIButton *)sender {
        if (self.isEditing) { // 如果是编辑状态,取消编辑
            
            // 更改文字
            [sender setTitle:@"Edit" forState:UIControlStateNormal];
            
            // 取消编辑
            [self setEditing:NO animated:YES];
        } else {
            
            // 更改文字
            [sender setTitle:@"Done" forState:UIControlStateNormal];
            
            // 开始编辑
            [self setEditing:YES animated:YES];
        }
    }
    
    /**
     *  添加表格时,必须保证 UITableView 对象当前显示的行数与数据源的提供的行数相同。
     *  所以,在添加之前,必须先创建一个新的 JXItem 对象并加入到 JXItemStore 中
     *
     *  @param sender 按钮
     */
    - (void)addClick:(UIButton *)sender {
        
        // 创建新的 JXItem 对象,并加入到 JXItemStore 中
        JXItem * newItem = [[JXItemStore sharedStore] createItem];
        
        // 获取新的对象在 allItem 数组中的索引
        NSInteger lastRow = [[[JXItemStore sharedStore] allItem] indexOfObject:newItem];
        NSIndexPath * indexPath = [NSIndexPath indexPathForRow:lastRow inSection:0];
        
        // 将新航插入 UITableView 对象
        [self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationTop];
    }
    @end

      构建并运行

  • 相关阅读:
    c# 三层结构的简单理解
    浅析C#鼠标右键如何添加
    三层结构开发的理解
    Windows快捷键大全
    command 中 ExecuteScalar() ExecuteNonQuery ()和ExecuteReader()的用法
    很拽的JSON
    FCKeditor的全局API
    WebForm_DoPostBackWithOptions 丢失的解决
    闭包的错误例子
    XPath学习笔记 XPath数据模型
  • 原文地址:https://www.cnblogs.com/wang-com/p/5911112.html
Copyright © 2011-2022 走看看