为啥我的单元格在我的 UITableView 中显示为空白?

Posted

技术标签:

【中文标题】为啥我的单元格在我的 UITableView 中显示为空白?【英文标题】:Why are my cells appearing blank in my UITableView?为什么我的单元格在我的 UITableView 中显示为空白? 【发布时间】:2013-04-25 22:03:14 【问题描述】:

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

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

正如我所说,除了故事板之外,一切都在代码中完成。我从 Core Data 获取单元格的信息,并通过将文章设置为单元格的 article 属性来构造单元格,然后将该文章设置为 CellFront UIViewarticle 属性。因为根据单元格包含的文章类型有两种单元格布局,所以在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;

ArticleCell.m中,我覆盖了文章的set方法,所以当上面的数据源方法调用它时,它也可以设置视图的article属性。

- (void)setArticle:(ArticleInfo *)article 
    _article = article;

    self.cellFront.article = article;

我还在ArticleCell.m 文件中创建了CellFrontCellBack UIViews:

- (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: 方法中调用以下方法,该方法根据文章的类型设置标签并将它们添加到子视图中。

- (void)addControlsToView 
    if ([self.article.isUserAddedText isEqualToNumber:@YES]) 
        UILabel *preview = [[UILabel alloc] initWithFrame:CGRectMake(20, 5, 280, 70)];
        preview.text = self.article.preview;
        preview.numberOfLines = 4;
        preview.font = [UIFont systemFontOfSize:16.0f];
        preview.textColor = [UIColor blackColor];
        preview.backgroundColor = [UIColor clearColor];
        [self addSubview:preview];
    
    else 
        UILabel *title = [[UILabel alloc] initWithFrame:CGRectMake(20, 10, 280, 20)];
        title.text = self.article.title;
        title.font = [UIFont boldSystemFontOfSize:18.0f];
        title.textColor = [UIColor blackColor];
        title.backgroundColor = [UIColor clearColor];
        [self addSubview:title];

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

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

这就是我认为相关的所有内容。为什么所有单元格都显示为空白?

【问题讨论】:

在storyboard中,是否将原型表视图单元格的Custom Class设置为ArticleCell 【参考方案1】:

如果您不使用故事板或 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方法每次cell都被重用,并且UILabel的初始化只有一次。我会将上面的代码移动到CellFront 上的文章属性的设置器中。例如,首先为标签声明一些属性

@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];

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

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

【讨论】:

您有故事板或NIB 以及您发布的代码吗? 是的,见第二段。 抱歉,错过了这一点,并假设由于您使用的 dequeue 方法,并且因为您在代码中创建了所有对象,因此您没有使用故事板。我编辑了我的答案。 不幸的是,这似乎什么也没做。 如果你能把项目或源代码链接发给我,我会看看。

以上是关于为啥我的单元格在我的 UITableView 中显示为空白?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的 UICollectionView 单元格在我的 swift ios 应用程序中不可点击?

UITableView 中的自定义单元格在滑动编辑后立即移动

iOS - 使 UITableView 与自定义单元格在按钮单击时可编辑

UITableView 单元格在首次加载时未显示

UITableview刷新单元格在部分标题下滚动

UITableView 单元格在向下滚动然后备份后消失