1

我想创建一个 uitableview 混合不同类型的项目来显示。对于每个项目,我想显示一些通用信息(始终相同的类型和样式)和一些细节(根据项目类型不同的类型和样式)。= 我需要某种“模板管理器”。

我使用 coredata(Item 是一个实体)存储和检索项目,通过 nsfetchedresultscontroller 将数据挂钩到 tableview,项目类型存储为名为 item_nature 的属性。

我正在使用故事板,所以首先我考虑使用不同的原型单元格,并在 cellForRowAtIndexPath 中,根据 item_nature 值分配所需的单元格原型。几乎可以工作,但由于我将拥有大约 10 种不同的项目,因此在故事板中管理 10 个原型单元并不是很实用。另外,我需要根据内容类型/长度调整行高,这种方法意味着很多冗余代码......

现在我尝试第二种方法,但无法使其工作。我的想法:

1> 在情节提要中,我只为每个项目类型创建一个原型单元。见下图,这个单元格由一张图像和两个标签(蓝色)+一个视图(红色)组成

在此处输入图像描述

蓝色区域将用于“通用信息”(相同的类型、大小和样式,无论项目,只有内容更改),红色区域就像一个容器,我通过根据 item_nature 添加特定子视图来调整特定模板

2> 在单元格自定义类中,我为三个标签和视图设置 IBOutlets,并将这些出口与情节提要中的 UIelements 链接

MainTLCustomCell.h

#import <UIKit/UIKit.h>
#import "CellTemplateContainer.h"

@interface MainTLCustomCell : UITableViewCell

@property (nonatomic, strong) IBOutlet UIImageView *aboIcon;
@property (nonatomic, strong) IBOutlet UILabel *itemAboName;
@property (nonatomic, strong) IBOutlet UILabel *itemDate;
@property (nonatomic, strong) IBOutlet CellTemplateContainer *itemTemplate;

@end

3> 我为每个项目模板创建一个专用的xib文件,例如BasicArticleItemTemplate.xib,ArticleWithPicItemTemplate.xib等这些xib应该根据项目的item_nature加载到视图容器中(单元格中仍然是红色)

4> 我创建了一个名为 CellTemplateContainer 的 UIView 子类,其属性为“templateType”,并将该类分配给原型单元格中的“容器”视图。由于这个视图是由情节提要实例化的,在 -initWithCoder 中(我也在 -awakeFromNib 中尝试过),我根据 templateType 属性的值(我将尝试从 tableViewController 发送的值)设置一个条件来添加子视图

单元格模板容器.h

@interface CellTemplateContainer : UIView {
    NSNumber *templateType;
    NSString *stringTemplateType;
}

// We'll choose the correct template to load according to item_nature passed to this property
@property (nonatomic, strong)NSNumber *templateType;
@property (nonatomic, strong)NSString *stringTemplateType;

@end

单元格模板容器.m

-(id)initWithCoder:(NSCoder *)aDecoder
{
    if ((self = [super initWithCoder:aDecoder]))
    {
        NSLog(@"initwithcoder /// self.templateType = %i", [self.templateType intValue]);       

        if (templateType == [NSNumber numberWithInt:1]) {
            [self addSubview:[[[NSBundle mainBundle] loadNibNamed:@"BasicArticleItemTemplate" owner:self options:nil] objectAtIndex:0]];
        } else if (self.templateType == [NSNumber numberWithInt:2]) {
            [self addSubview:[[[NSBundle mainBundle] loadNibNamed:@"ArticleWithPicItemTemplate" owner:self options:nil] objectAtIndex:0]];
        }
    }
    return self;
}

5> 在 tableViewClass 中,在 -cellForRowAtIndexPath 中,我设置了三个泛型标签的值,并尝试为视图容器的属性“templateType”设置值:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    Item *item = [self.fetchedResultsController objectAtIndexPath:indexPath];

    static NSString *CellIdentifier = @"kopTLCell";

    MainTLCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    // Abo icon & displayName
    UIImage *aboIcon = [UIImage imageNamed:item.estProduitPar.abo_icon];
    cell.aboIcon.image = aboIcon;
    cell.itemAboName.text = item.estProduitPar.abo_displayName;

    // Date
    _dateFormatter = [[NSDateFormatter alloc] init];
    //[_dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
    [_dateFormatter setTimeStyle:NSDateFormatterShortStyle];
    [_dateFormatter setDateStyle:NSDateFormatterMediumStyle];
    [_dateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"fr_FR"]];
    [_dateFormatter setDoesRelativeDateFormatting:YES];
    NSString *stringFromDate = [_dateFormatter stringFromDate:item.date];
    cell.itemDate.text = stringFromDate;

    cell.itemTemplate.templateType = item.item_nature;
    cell.itemTemplate.stringTemplateType = @"hello";

    return cell;
}

只要我不对 templateType 值设置条件,在 -initWithCoder 中添加子视图就可以很好地工作。

我的问题在这里:

cell.itemTemplate.templateType = item.item_nature;

itemTemplate 视图永远不会得到这个值(总是 0,所以我假设为 nil)。我仍然对对象与实例感到困惑,并且显然不掌握调用 init 方法的顺序。但我认为我可以在容器视图初始化之前或期间将值“发送”到容器视图以考虑...我也希望通过这种方法我可以轻松地添加一个新的 item_nature 和关联的模板模型 + 具有更简单的方法来管理有关单元格高度计算的代码。

所以,两个问题: - 我做错了什么?- 在此类项目中,您推荐什么作为处理单元模板管理的好方法?

谢谢

4

1 回答 1

0

到你打电话的时候cell.itemTemplate.templateType = item.item_nature;initWithCoderCellTemplateContainer已经过去了。

建议您将您的单元设置代码放在一个设置器中,例如:

-(void)setTemplateType:(NSNumber*) templateType {
    _templateType = templateType;

    if ([templateType intValue] == 1) {
        [self addSubview:[[[NSBundle mainBundle] loadNibNamed:@"BasicArticleItemTemplate" owner:self options:nil] objectAtIndex:0]];
    } else if ([templateType intValue] == 2) {
        [self addSubview:[[[NSBundle mainBundle] loadNibNamed:@"ArticleWithPicItemTemplate" owner:self options:nil] objectAtIndex:0]];
    }
}

此外,您应该考虑到您的创建和NSDateFormatter配置cellForRowAtIndexPath

于 2013-10-04T14:37:14.577 回答