ios - 为什么我的单元格在我的 UITableView 中显示为空白?

标签 ios objective-c uitableview nsfetchedresultscontroller

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

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

正如我所说,除了 Storyboard 外,所有内容都是用代码完成的。我从 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 中,我覆盖了 article 的 set 方法,因此当上面的数据源方法调用它时,它也可以设置 View 的 article 属性。

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

    self.cellFront.article = article;
}

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

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

- (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 或 NIB 来定义您的 View ,则永远不会调用 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;
}

如果您尝试使用 Storyboard ,那么您正在错误地出列单元格,请替换:

ArticleCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

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

与:

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

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

这是 documentation 的链接对于这种方法。


附加信息

您也不会在单元格中看到数据,因为您是在用于初始化 View 的同一代码块中设置标签文本值。基本上,您需要执行以下操作:

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

...这部分的addControlsToView方法每次cell都被重用,而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];
}

然后像这样设置控件,可能来自 article 属性的 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;
    }
}

关于ios - 为什么我的单元格在我的 UITableView 中显示为空白?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16225511/

相关文章:

ios - 如何在加载 tableView 后更新 UITableViewCell 高度

ios - Swift,无法使用 'deep link' 打开第二个应用程序

iphone - 如何从 objective-c 在 iPhone 上启动 map 应用程序

objective-c - 使用 MKTileOverlay 和 MKTileOverlayRenderer

c++ - iOS:在 Objective-C++ 中定义和使用 C++

iphone - 在 UITableview 中选择多行

ios - 如何在Swift 3中识别editingStyle中的.delete以删除tableview中的单元格

ios - 在已创建的对象 "the name of the class i' 上找不到属性”,并且 View Controller 无法识别其中定义的方法

ios - 保存日历后,事件错误记录到控制台

ios - 如何更改 UIButton 的突出显示颜色?