通过IB将属性设置为自定义子视图init(用于uitableviewcell模板)

时间:2013-10-04 13:46:38

标签: ios objective-c uitableview properties initwithcoder

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

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

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

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

1>在故事板中,我只创建了一个用于每种项目类型的原型单元格。参见下图,此单元格由一个图像和两个标签(蓝色)+一个视图(红色)

组成

enter image description here

蓝色区域将用于“通用信息”(相同的类型,大小和样式,无论项目,只有内容更改),红色区域就像一个容器,我通过添加特定的子视图来调整特定的模板根据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&GT;我为每个项目模板创建一个专用的xib文件,例如BasicArticleItemTemplate.xib,ArticleWithPicItemTemplate.xib等这些xib应该根据项目的item_nature加载到视图容器中(仍然是单元格中的红色)

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

CellTemplateContainer.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

CellTemplateContainer.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,in -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,所以我假设是零)。我仍然对象与实例混淆,显然不掌握调用init方法的顺序。但我认为我能够在容器视图中“发送”一个值,以便在初始化之前或期间考虑... 我也希望通过这种方法,我可以轻松地将新的item_nature和相关的模板添加到模型中+有一种更简单的方法来管理有关单元格高度计算的代码。

所以,两个问题: - 我究竟做错了什么 ? - 您认为在这种项目中处理细胞模板管理的好方法是什么?

由于

1 个答案:

答案 0 :(得分:0)

当您致电cell.itemTemplate.templateType = item.item_nature;时,initWithCoder上的CellTemplateContainer已经过去了。

建议您将单元格设置代码放在setter中,例如:

-(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的创建和配置