DXTableViewModel 0.1.0

DXTableViewModel 0.1.0

测试测试过
语言语言 Obj-CObjective C
许可协议 MIT
发布上次发布2014年12月

未声明 维护。



  • 作者:
  • Alexander Ignatenko

UITableView 的面向对象表示。以声明方式描述表格视图。适用于构建带有很多不同单元格子类的复杂表格视图表单。

它只包含三个类

  • DXTableViewModel - 实现表格视图的所有代理和数据源方法。
  • DXTableViewSection - 表示表格视图的分区。
  • DXTableViewRow - 表示表格视图的行。

分区和单元格(行)分别由 DXTableViewSectionDXTableViewRow 对象表示。DXTableViewModel 本质上是表格视图的代理和数据源,根据通过块 API 在分区和行对象提供的数据配置表格视图。

注意

该项目仍处于早期开发阶段,因此请谨慎使用。本阶段的 API 打破性更改可能性很大。欢迎任何错误报告、建议或请求合并。

主要功能

  • 易于使用:基于块的 API 命名与 UITableView 的代理和数据源方法相似。
  • 易于集成:支持自定义 UITableViewCell 和 UIViewController。
  • 易于通过动画或无动画从表格视图中添加/删除分区和行。
  • 支持 Storyboard 和 xib。
  • 简单的数据绑定功能,简化了可编辑表单的创建。(可选)
  • 跟踪自 UIControl 子类和 UITextView 的更改,在单元格被重新使用之前缓存单元格状态。(可选)
  • 通过 rowHeightBlock 属性动态设置行高。
  • 通过 cellClasscellNib 属性提供单元格类的注册和 xib。
  • 完全使用 appledoc 风格文档化的头文件。(目前正在进行中…)

示例

构建在选中时显示警告的单元格表格视图

    self.tableViewModel = [[DXTableViewModel alloc] init];
    DXTableViewSection *buttonsSection = [[DXTableViewSection alloc] initWithName:@"Buttons"];
    buttonsSection.headerTitle = @"Buttons";
    DXTableViewRow *actionRow = [[DXTableViewRow alloc] initWithCellReuseIdentifier:@"ActionCell"];
    actionRow.cellClass = [UITableViewCell class];  
    actionRow.configureCellBlock = ^(DXTableViewRow *row, UITableViewCell *cell) {
        cell.textLabel.text = @"Tap Me";
    };
    actionRow.didSelectRowBlock = ^(DXTableViewRow *row) {
        // here row is a reference to actionRow object, that avoids need to make weak reference in order to access to row's properties from this block
        [[[UIAlertView alloc] initWithTitle:@"Action"
                                   message:@"You did tap \"Tap Me\" button"
                                  delegate:nil
                         cancelButtonTitle:@"OK"
                         otherButtonTitles:nil] show];
        [row.tableView deselectRowAtIndexPath:row.rowIndexPath animated:YES];
    };
    [buttonsSection addRow:actionRow];
    [self.tableViewModel addSection:buttonsSection];
    self.tableViewModel.tableView = self.tableView; // this will implicitly set delegate and datasource of table view to tableViewModel

行和分区的动画处理

    // assume section object is already added to table view model, newSection is configured with rows and table view is being displayed
    [tableViewModel beginUpdates];

    NSArray *rows = @[itemRow1, itemRow2]; // Array of DXTableViewRow objects
    [section insertRows:rows afterRow:addItemRow withRowAnimation:UITableViewRowAnimationAutomatic];

    NSArray *rowsToDelete = @[itemRow3];
    [section deleteRows:rowsToDelete withRowAnimation:UITableViewRowAnimationAutomatic];

    [tableViewModel insertSections:@[newSection] afterSectionWithName:@"SomeOtherSection" withRowAnimation:UITableViewRowAnimationAutomatic];

    [tableViewModel endUpdates];

或者,您可以手动修改表格视图,DXTableViewModel 类将提供足够的信息

    NSInteger *deletedSectionIndex = [tableViewModel deleteSectionWithName:@"SomeSection"];
    NSIndexPath *deletedRowIndexPath = [itemsSection removeRow:itemRow];
    [self.tableView beginUpdates];
    self.tableView deleteSections:[NSIndexSet indexSetWithIndex:deletedSectionIndex] withRowAnimation:UITableViewRowAnimationAutomatic];    
    self.tableView deleteRowsAtIndexPaths:@[deletedRowIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
    [self.tableView endUpdates];

创建可编辑表单。将对象绑定到从 xib 创建的单元格所创建的行。绑定对象的键路径将可通过索引从行对象访问

    DXTableViewRow *stepperRow = [[DXTableViewRow alloc] initWithCellReuseIdentifier:@"StepperCell"];
    stepperRow.cellNib = [UINib nibWithNibName:@"StepperCell" bundle:nil];
    [stepperRow bindObject:self.item withKeyPaths:@[@"count"]];
    stepperRow.configureCellBlock = ^(DXTableViewRow *row, StepperCell *cell) {
        // here row is a reference to stepperRow object, that avoids need to make weak reference in order to access to row's properties from this block
        cell.titleLabel.text = @"Number of items";
        cell.valueLabel.text = [NSString stringWithFormat:@"%@", row[@"count"]]; // count is a bound key path from 
        cell.stepper.value = [row[@"count"] doubleValue];
        [row becomeTargetOfControl:cell.stepper forControlEvents:UIControlEventValueChanged withBlock:^(UIStepper *stepper){
            row[@"count"] = @(stepper.value); // cache steppre value on each value changed event
            cell.valueLabel.text = [NSString stringWithFormat:@"%@", row[@"count"]];
        }]; // this will add row as target of stepper control in order to cache control's state
    };
    [textSection addRow:stepperRow];
    [tableViewModel addSection:textSection];

    // …

    // call updateRowObjects to push cached changes into bound objects:
    [tableViewModel updateRowObjects];

    // …

    // call reloadRowBoundData to refresh cached data in rows from bound objects:
    [tableViewModel reloadRowBoundData];

将参数应用于分区中的所有行

    for (DXTableViewRow *row in textSection.rows) {
        row.editingStyle = UITableViewCellEditingStyleNone;
        row.shouldIndentWhileEditingRow = NO;
    }

安装

DXTableViewModel 通过 Cocoa Pods 提供。将其添加到 Podfile 中

    pod 'DXTableViewModel',  '~> 0.1.0'

您还可以直接从 DXTableViewModel 目录中获取源文件并将其添加到项目中。

享受!