【问题标题】:I want the same UITableView style across various table views - how can i do this?我希望在各种表格视图中使用相同的 UITableView 样式 - 我该怎么做?
【发布时间】:2012-07-14 17:37:52
【问题描述】:

例如,我有一个设置菜单,它通向其他菜单,并且都具有相同的样式。表格视图单元格自定义是这样完成的:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = (UITableViewCell *)[self dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                      reuseIdentifier:CellIdentifier];

        cell.contentView.backgroundColor = [UIColor clearColor];
        cell.textLabel.backgroundColor = [UIColor clearColor];
    }

    BOOL isFirstRowInSection = NO;

    if (indexPath.row == 0) isFirstRowInSection = YES;

    BOOL isLastRowInSection = NO;

    int numberOfRowsInSection = [tableView.dataSource tableView:self numberOfRowsInSection:indexPath.section];

    if (indexPath.section == 0 && indexPath.row == numberOfRowsInSection - 1) {
        isLastRowInSection = YES;
    }

    UIImageView *imageView = [[UIImageView alloc] initWithFrame:cell.bounds];
    imageView.image = cellBackgroundImage(cell.bounds.size, isFirstRowInSection, isLastRowInSection);

    cell.backgroundView = imageView;

    //cell.textLabel.text = @"This is a cell";

    return cell;
}

我希望主设置菜单和所有子菜单都使用这个类,但是虽然我希望它们提供自己的数据,例如每个单元格的文本,但我希望它从这里获取单元格样式方法。

我怎样才能做到这一点?目前的想法是将部分数据源协议复制到我自己的委托中,以便他们可以响应。

【问题讨论】:

    标签: iphone objective-c ios uitableview customization


    【解决方案1】:

    您可以创建 UITableViewCell 的特定子类并在单元格本身中实现您的视觉特征。

    如果你在 InterfaceBuilder 中创建一个子类和一个 nib 文件,你可以有一个类似的类方法

    + (NSString *)cellIdentifier {
        return NSStringFromClass([self class]);
    }
    
    
    + (id)cellForTableView:(UITableView *)tableView {
        NSString *cellID = [self cellIdentifier];
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
        if (cell == nil) {
            NSArray *nibObjects = [[self nib] instantiateWithOwner:nil options:nil];
            NSAssert2(([nibObjects count] > 0) && 
                      [[nibObjects objectAtIndex:0] isKindOfClass:[self class]],
                      @"Nib '%@' does not appear to contain a valid %@", 
                      [self nibName], NSStringFromClass([self class]));
            cell = [nibObjects objectAtIndex:0];
        }
        return cell;    
    }
    

    所以,如果您已经定义了一个类(例如 MyTableViewCell)并在 IB 中构建接口,您确保将 FileOwner 设为 MyTableViewCell 的一个对象,并拥有各种子类特定视觉对象的 IBOutlets,并且 Bob 是您的叔叔.

    然后在 tableViewController 的 cellForRowAtIndexPath 方法中使用类似

    MyTableViewCell *cell = [MyTableViewCell cellForTableView:tableView];
    

    通过这种方式,大部分可视化呈现逻辑都保留在 Interface Builder 代码中。如果您要制作通用应用程序,则必须创建两个 nib 文件,但这并不太难。

    【讨论】:

      【解决方案2】:

      实现这一点的一种方法是让您的“其他菜单”——这个 tableview“进入”的那些菜单——调用这个 tableview 的 - tableView:cellForRowAtIndexPath: 方法。看起来像这样:

      ChildTableViewController.m:

      -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
          // Somehow, you'll need to give this child VC a pointer to the
          // "root" tableview – I'll pretend that pointer is "rootTableView"
          return [rootTableView tableView:tableView cellForRowAtIndexPath:indexPath];
      }
      

      您必须确保您对从该方法返回的内容很了解,因为现在不仅有一个 tableview,而且许多都在使用该方法来获取他们的单元格。您可以通过检查 UITableView 要求的单元格来做到这一点:

      -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
          static NSString *CellIdentifier = @"Cell";
          UITableViewCell *cell = (UITableViewCell *)[self dequeueReusableCellWithIdentifier:CellIdentifier];
          if (cell == nil) {
              cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                            reuseIdentifier:CellIdentifier];
      
              cell.contentView.backgroundColor = [UIColor clearColor];
              cell.textLabel.backgroundColor = [UIColor clearColor];
          }
      
          BOOL isFirstRowInSection = NO;
      
          if (indexPath.row == 0) isFirstRowInSection = YES;
      
          BOOL isLastRowInSection = NO;
      
          int numberOfRowsInSection = [tableView.dataSource tableView:self numberOfRowsInSection:indexPath.section];
      
          if (indexPath.section == 0 && indexPath.row == numberOfRowsInSection - 1) {
              isLastRowInSection = YES;
          }
      
          UIImageView *imageView = [[UIImageView alloc] initWithFrame:cell.bounds];
          imageView.image = cellBackgroundImage(cell.bounds.size, isFirstRowInSection, isLastRowInSection);
      
          cell.backgroundView = imageView;
      
          //cell.textLabel.text = @"This is a cell";
      
          // Now, all your cells have the same formatting; do your custom 
          // data grabbing or whatever you need to do for the different
          // tableviews
          if (tableview == [self view]) {
              return cell;
          } else if (tableview = [self childTableView1]) {
              // Do the setup you'd want for your first child tableview
              return cell;
          } else if (tableview = [self childTableView2]) {
              // Do the setup you'd want for your second child tableview
              return cell;
          }   // More if statements as needed
      
          return cell;
      }
      

      不过,将代码从您显示的方法中复制并粘贴到每个“子”表视图的 - tableView:cellForRowAtIndexPath: 方法中可能会更简洁。它不会太长,而且设置起来也不会那么令人头疼。

      【讨论】:

      • 谢谢。不过,复制和粘贴代码从来都不是一个好主意。假设我在一个地方更改了它,那么除非我记得将它复制并粘贴到所有其他地方,否则我手上就会一团糟。
      • 完全正确。让我知道第一个解决方案是否效果更好。您还可以在 UITableViewCell 上实现一个类别,当您调用 [UITableViewCell formattedCell] 之类的东西时,它会吐出一个预先格式化的单元格,如果您打算经常使用这样的单元格。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-22
      • 2016-04-01
      • 1970-01-01
      相关资源
      最近更新 更多