【问题标题】:How to add a custom cell to the bottom of a UITableView?如何将自定义单元格添加到 UITableView 的底部?
【发布时间】:2012-01-31 21:21:16
【问题描述】:

我有一个 UITableView,其中数据源是使用 NSFetchRequest 的 Core Data。核心数据包含从我网站上的数据库下载的新闻项目。默认情况下,Core Data 包含 50 个最新项目,当到达 UITableView 的底部时,会延迟下载较旧的项目。

我目前正在使用tableView:numberOfRowsInSection 方法处理这个问题,我在最后一部分返回+1,这是我的“正在加载项目”单元格。在 tableView:cellForRowAtIndexPath 方法中,我正在创建“加载项”单元格,此时 IndexPath 是最后一节中的最后一行。

问题是,当下载新数据时,以前是“加载项”单元格的单元格现在是常规新闻项单元格。但是当我滚动离开单元格并返回时,首先重新加载单元格。

我可以存储“加载项”单元格的 indexPath 并在延迟加载完成后重新加载该单元格。但我想知道,是否有更好的解决方案来解决这个问题?

EDIT1:

这是我创建“加载项”UITableViewCell 的过程。

cell.textLabel.text = [NSString stringWithFormat:@"%@\u2026", NSLocalizedString(@"LOADING_MORE", nil)];

UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];

UIImage *spacer = [UIImage imageNamed:@"Spacer"];

UIGraphicsBeginImageContext(spinner.frame.size);
[spacer drawInRect:CGRectMake(0,0,spinner.frame.size.width,spinner.frame.size.height)];
UIImage* resizedSpacer = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

cell.imageView.image = resizedSpacer;
[cell.imageView addSubview:spinner];
[spinner startAnimating];

EDIT2:

我正在尝试使用以下代码“设计”footerView。目前,活动指示器位于左上角,标签不可见。

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
    NSInteger sectionsAmount = [tableView numberOfSections];
    if (section == sectionsAmount - 1) {
        return 20;
    }
    return 0;
}

- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
    NSInteger sectionsAmount = [tableView numberOfSections];
    if (section == sectionsAmount - 1) {
        if (_tableFooterView==nil) {
            UIView *view = [[UIView alloc] init];

            UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];

            UIImage *spacer = [UIImage imageNamed:@"Spacer"];

            UIGraphicsBeginImageContext(spinner.frame.size);
            [spacer drawInRect:CGRectMake(0,0,spinner.frame.size.width,spinner.frame.size.height)];
            UIImage* resizedSpacer = UIGraphicsGetImageFromCurrentImageContext();
            UIGraphicsEndImageContext();

            UIImageView *imageView = [[UIImageView alloc] init];

            imageView.image = resizedSpacer;
            [imageView addSubview:spinner];
            [spinner startAnimating];

            [view addSubview:imageView];

            UILabel *label = [[UILabel alloc] init];
            label.text = [NSString stringWithFormat:@"%@\u2026", NSLocalizedString(@"LOADING_MORE", nil)];
            [view addSubview:label];

            _tableFooterView = view;
        }
        return self.tableFooterView;
    }
    return nil;
}

如何将 UIView 更改为如下图所示:

EDIT3:

这是我的 setupTableFooterView,我在其中将视图分配给 tableFooterView。该方法是从 viewDidLoad 调用的。

- (void) setupTableFooterView {
    UIView *view = [[UIView alloc] init];

    UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];

    UIImage *spacer = [UIImage imageNamed:@"Spacer"];

    UIGraphicsBeginImageContext(spinner.frame.size);
    [spacer drawInRect:CGRectMake(0,0,spinner.frame.size.width,spinner.frame.size.height)];
    UIImage* resizedSpacer = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    UIImageView *imageView = [[UIImageView alloc] init];

    imageView.image = resizedSpacer;
    [imageView addSubview:spinner];
    [spinner startAnimating];

    imageView.frame = CGRectMake(10, 11, 20, 20);
    [view addSubview:imageView];

    UILabel *label = [[UILabel alloc] init];
    label.text = [NSString stringWithFormat:@"%@\u2026", NSLocalizedString(@"LOADING_MORE", nil)];
    [label setFont:[UIFont italicSystemFontOfSize:13]];
    [label setFrame:CGRectMake(40, 0, 270, 43)];
    [view addSubview:label];

    self.tableView.tableFooterView = view;
}

【问题讨论】:

    标签: objective-c ios cocoa-touch uitableview


    【解决方案1】:

    使用 UITableView tableFooterView 代替该消息。这样您就不必摆弄节/行结构。

    来自UITableView reference

    tableFooterView
    

    返回显示在表格下方的附件视图。

    @property(nonatomic, retain) UIView *tableFooterView
    

    讨论

    默认值为无。表格页脚视图不同于 节页脚。

    【讨论】:

    • 感谢您的评论,我认为这可能是我的解决方案。我没有成功尝试设置 tableFooterView。你能看看我的EDIT2吗?
    • 您正在植入sectionFooter,我建议使用tableFooter。当然 sectionFooter 是一个选项,但我建议使用 tableFooter 代替。请检查链接的参考。
    • 对不起,你说对了。我已将视图初始化添加到 viewDidLoad。你能看看我的EDIT3吗?
    • @DennisMadsen 您的标签不可见,因为您从未为其分配框架。
    • 谢谢。当 tableFooterView 中显示“正在加载更多”消息时,我需要开始延迟加载。我该如何处理?
    【解决方案2】:

    您没有在延迟下载回调中使用 [tableView reloadData] 吗?因此,当服务器发回更多结果并将它们添加到您的数据源时,表格绘制逻辑会被重新调用,并且对 numberOfRowsInSection 的添加是否正确?

    此外,我认为您关于将表格的最后一个单元格分配为“加载单元格”的建议可能会很好。合成一个保留的属性或成员变量并将您的 LoadingCell 引用存储在其中,并在调用所有单元创建逻辑之前检查 indexPath。如果它是表格中的最后一个单元格,则返回 self.loadingCell。

    【讨论】:

      【解决方案3】:

      我假设您当前的表格视图中只有一个部分。改为制作两个部分。第一部分仅包含普通数据行。第二部分仅包含“加载项”单元格。

      当有新数据可用时,使用insertRowsAtIndexPaths:withRowAnimation: 通知表视图新行。

      【讨论】:

      • 抱歉,我有多个部分。
      猜你喜欢
      • 2012-04-10
      • 1970-01-01
      • 2011-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-09
      相关资源
      最近更新 更多