为什么我的细胞在我的UITableView中显示为空白?

时间:2013-04-25 22:03:15

标签: ios objective-c uitableview nsfetchedresultscontroller

我的UITableView有一个奇怪的结构。基本上,我有ArticleCell个对象(UITableViewCell的子类)组成表,每个ArticleCell由“前”视图和“后”视图组成。前视图包含所有标签和用户看到的内容,而背面有左右两个图标。这两个视图的想法是,用户可以向右或向左滑动顶视图以快速选择一个选项(类似于Reeder)。

我在故事板中稍微实现了这一点,但主要是在代码中。我在故事板中唯一做的就是完成了UITableViewController的布局,并命名了原型单元格的标识符(标识符:“ArticleCell”)。

除了故事板,正如我所说,一切都是在代码中完成的。我从Core Data获取单元格的信息,并通过将文章设置为单元格的article属性来构建单元格,然后将该文章设置为CellFront UIView的{​​{1}}属性。因为有两种单元格布局,具体取决于单元格所包含的文章类型,在article中,它会检查单元格的类型(称为CellFront的属性)并相应地创建布局。

但正如我所说,当应用程序加载时,没有任何内容显示,所有单元格都会加载,我可以点击它们去查看其内容,但单元格本身是空白的。

相关代码如下:

细胞数据来源:

isUserAddedText

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { ArticleInfo *articleInfo = [self.fetchedResultsController objectAtIndexPath:indexPath]; static NSString *CellIdentifier = @"ArticleCell"; ArticleCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[ArticleCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; } cell.article = articleInfo; return cell; } 中,我覆盖了文章的set方法,所以当上面的数据源方法调用它时,它也可以设置视图的ArticleCell.m属性。

article

我还在- (void)setArticle:(ArticleInfo *)article { _article = article; self.cellFront.article = article; } 文件中创建了CellFrontCellBack UIView

ArticleCell.m

- (void)awakeFromNib { [super awakeFromNib]; self.cellBack = [[CellBack alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, 80)]; [self.contentView addSubview:self.cellBack]; self.cellFront = [[CellFront alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, 80)]; [self.contentView addSubview:self.cellFront]; } 然后在其CellFront.m方法中调用以下方法,该方法根据文章的类型设置标签并将其添加到子视图中。

initWithFrame:

这就是我认为与之相关的一切。为什么所有单元格都显示为空白?

1 个答案:

答案 0 :(得分:2)

如果您不使用storyboard 或NIB来定义您的观看次数,则永远不会调用awakeFromNib:

以下是documentation

您应该尝试覆盖initWithStyle:reuseIdentifier:而不是awakeFromNib:

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];

    if (self != nil) {
        // DO STUFF
    }

    return self;
}

如果您尝试使用故事板,则表示您错误地将单元格排队,请替换:

ArticleCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell == nil) {
    cell = [[ArticleCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}

使用:

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

如果队列中没有新单元格,则此方法将从故事板中初始化新单元格。你使用的方法不会。这意味着有时单元格将等于nil,然后使用initWithStyle:reuseIdentifier:方法初始化新单元格,这不会调用awakeFromNib,因为您没有从NIB解码它。

以下是此方法documentation的链接。


其他信息

您也不会在单元格中看到数据,因为您要在用于初始化视图的同一代码块中设置标签文本值。基本上,你需要这样做:

...
preview.text = self.article.preview;
...

...每次重复使用单元格时addControlsToView方法的这一部分,以及UILabel的初始化仅一次。我将上面的代码移到CellFront上的文章属性的setter中。例如,首先声明标签的一些属性

@property (nonatomic, strong) UILabel *preview1Label;
@property (nonatomic, strong) UILabel *titleLabel;
@property (nonatomic, strong) UILabel *URLLabel;
@property (nonatomic, strong) UILabel *preview2Label;

然后像这样初始化控件

- (void)initControls {
    self.preview1 = [[UILabel alloc] initWithFrame:CGRectMake(20, 5, 280, 70)];
    self.preview1.text = self.article.preview;
    self.preview1.numberOfLines = 4;
    self.preview1.font = [UIFont systemFontOfSize:16.0f];
    self.preview1.textColor = [UIColor blackColor];
    self.preview1.backgroundColor = [UIColor clearColor];
    [self addSubview:self.preview1];

    self.title = [[UILabel alloc] initWithFrame:CGRectMake(20, 10, 280, 20)];
    self.title.text = self.article.title;
    self.title.font = [UIFont boldSystemFontOfSize:18.0f];
    self.title.textColor = [UIColor blackColor];
    self.title.backgroundColor = [UIColor clearColor];
    [self addSubview:self.title];

    self.URL = [[UILabel alloc] initWithFrame:CGRectMake(20, 35, 280, 20)];
    self.URL.text = self.article.url;
    self.URL.font = [UIFont systemFontOfSize:16.0f];
    self.URL.textColor = [UIColor blackColor];
    self.URL.backgroundColor = [UIColor clearColor];
    [self addSubview:self.URL];

    self.preview2 = [[UILabel alloc] initWithFrame:CGRectMake(20, 60, 280, 40)];
    self.preview2.text = self.article.preview;
    self.preview2.numberOfLines = 2;
    self.preview2.font = [UIFont systemFontOfSize:16.0f];
    self.preview2.textColor = [UIColor grayColor];
    self.preview2.backgroundColor = [UIColor clearColor];
    [self addSubview:self.preview2];
}

然后这样设置控件,可能来自文章属性的setter。

- (void)setControls {
    if ([self.article.isUserAddedText isEqualToNumber:@YES]) {
        self.preview1.hidden = NO;
        self.preview1.text = self.article.preview;
        self.title.hidden = YES;
        self.title.text = nil;
        self.URL.hidden = YES;
        self.URL.text = nil;
        self.preview2.hidden = YES;
        self.preview2.text = nil;
    }
    else {
        self.preview1.hidden = YES;
        self.preview1.text = nil;
        self.title.hidden = NO;
        self.title.text = self.article.title;
        self.URL.hidden = NO;
        self.URL.text = self.article.url;
        self.preview2.hidden = NO;
        self.preview2.text = self.article.preview;
    }
}