WAMSimpleDataSource,更优雅的编写静态UITableView

oton0320 7年前
   <h3>序</h3>    <p>相信做iOS开发的小伙伴们经常会遇到这样的页面:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/8eb6b945cf9c52575b19785b74e0d456.png"> <img src="https://simg.open-open.com/show/279cbce17c4f1938304033bb3310c2db.png"></p>    <p>对于这样的静态列表我们可以直接用 storyboard 拖一个出来,或者直接用代码创建。我个人的话会选择用代码直接创建,但是之前一直有的问题是没有较好的数据源表示方式,需要对 indexPath 进行硬编码,这导致了在 tableView 的代理里面需要进行判断:</p>    <pre>  <code class="language-objectivec">if (indexPath.section == 0) {      if (indexPath.row == 0) { // email          // do something      } else if (indexPath.row == 1) { // phone          // do something      }  } else if (indexPath.section == 1) {      // do something  }</code></pre>    <p>稍微好点的会在相关的判断边上做注释,但是这样写依然容易在往后(产品)调整顺序时调整了一个地方而忘记另外的,总的来说就是代码不够优雅。基于这样的背景,在尝试了各种方式之后,产生了一个可行的解决方案 —— WAMSimpleDataSource。</p>    <h3>设计思路</h3>    <p>在定义 WAMCellInfo 和 WAMSectionInfo 两个类时我选择引入别名( alias )来解决 indexPath 的硬编码问题(可能有人会说alias也是硬编码,但这样做提升了代码的可读性=0=)。</p>    <p>WAMCellInfo</p>    <p>WAMCellInfo 为 cell 的创建提供了最基本的信息,如 reuseIdentifier ,title,detail。用户也能传入自定义的 cell 而不必担心循环引用的问题。</p>    <p>WAMSectionInfo</p>    <p>WAMSectionInfo 作为 WAMCellInfo 的容器,提供了 <strong>添加</strong> , <strong>删除</strong> , <strong>替换</strong> ,以及基于 alias 对 WAMCellInfo 和 WAMCellInfo 的 <strong>索引</strong> 方法。</p>    <p>WAMDataSource</p>    <p>WAMDataSource 是所有 WAMSectionInfo 的容器,同样提供了 <strong>添加</strong> , <strong>删除</strong> , <strong>替换</strong> ,以及基于 alias 对 WAMSectionInfo 的 <strong>索引</strong> 方法。</p>    <h3>Demo</h3>    <p>让我们就以一个简单的 demo 看下 WAMSimpleDataSource 在静态列表中如何能让代码看起来更简洁。</p>    <pre>  <code class="language-objectivec">static NSString *const kReuseIdentifier     = @"tableViewCellIdentifier";  static NSString *const kIdentifierCellAlias = @"kIdentifierCellAlias";  static NSString *const kSelfDefineCellAlias = @"kSelfDefineCellAlias";    static NSString *const kSectionZeroAlias = @"kSectionZeroAlias";  static NSString *const kSectionOneAlias  = @"kSectionOneAlias";    #pragma mark - Initialization    // section info初始化  WAMSectionInfo *zero = [WAMSectionInfo infoWithCellInfos:@[] alias:kSectionZeroAlias];  // 添加操作,cell info初始化  [zero appendingCellInfo:[WAMCellInfo infoWithSelfDefineCell:self.customizedCell alias:kSelfDefineCellAlias]];    WAMSectionInfo *one = [WAMSectionInfo infoWithCellInfos:@[          [WAMCellInfo infoWithReuseIdentifier:kReuseIdentifier title:nil detail:nil alias:kIdentifierCellAlias]      ] alias:@"oneSectionAlias"];    // data source初始化  self.dataSource = [WAMDataSource dataSourceWithSectionInfos:@[zero, one]];    #pragma mark - UITableViewDataSource    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {      return self.dataSource.sectionInfos.count;  }    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {      return self.dataSource.sectionInfos[section].cellInfos.count;  }    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {      WAMCellInfo *cellInfo = self.dataSource.sectionInfos[indexPath.section].cellInfos[indexPath.row];      __kindof UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellInfo.identifier forIndexPath:indexPath];        // 根据不同的alias进行不同的操作      if ([cellInfo.alias isEqualToString:kSelfDefineCellAlias]) {          // do something      } else if ([[cellInfo.alias isEqualToString:kIdentifierCellAlias]) {          // do something      }      .      .      .        return cell;  }    - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {      return self.dataSource.sectionInfos[section].sectionHeaderHeight;  }    - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {      return self.dataSource.sectionInfos[section].sectionFooterHeight;  }</code></pre>    <h3>总结与缺陷</h3>    <p>现在的 WAMDataSource 还没办法做到直接作为 tableView 的数据源,这是在今后的更新中会解决的问题。虽然 WAMSimpleDataSource 并没有减少很多代码量,但能提升静态列表中代码的可读性以及可维护性,个人觉得还是值得的。</p>    <p> </p>    <p> </p>