我想在各种表视图中使用相同的UITableView样式 - 我该怎么做?

时间:2012-07-14 17:37:53

标签: iphone objective-c ios uitableview customization

因此,例如,我有一个设置菜单,可以进入其他菜单,并且所有菜单都具有相同的样式。表视图单元格结构如下所示:

-(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;
}

我希望这个类可以被主设置菜单和所有子菜单使用,但是我希望它们提供自己的数据,比如每个单元格的文本,我希望它从这里采用单元格样式方法。

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

2 个答案:

答案 0 :(得分: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;    
}

因此,如果您已经在IB中定义了一个类(比如MyTableViewCell)和Build the Interface,那么请确保使FileOwner成为MyTableViewCell的一个对象,并拥有各种子类特定视觉对象的IBOutlet,Bob是您的叔叔

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

的方法
MyTableViewCell *cell = [MyTableViewCell cellForTableView:tableView];

这样,大部分可视化表示逻辑都在Interface Builder代码中维护。如果您正在制作通用应用程序,则必须创建两个nib文件,但这并不太难。

答案 1 :(得分:0)

实现这一目标的一种方法是让你的“其他菜单” - 这个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:方法中可能更简洁。这不会太长,而且设置起来也不会那么令人头痛。