UITableView tableFooterView显示在UITableView的顶部 - 错误 [英] UITableView tableFooterView shows at the top of the UITableView - wrong

查看:207
本文介绍了UITableView tableFooterView显示在UITableView的顶部 - 错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个非常简单的测试用例来重现这个问题。

I have created a very simple test case to reproduce this issue.

我试图以编程方式将页脚视图设置为tableview。请注意,我指的是桌面视图最底部的页脚 - 不是部分页脚(大多数堆栈溢出答案会混淆它们)。

I am trying to set a footer view programmatically to a tableview. Please note that I am referring to the footer at the very bottom of the tableview - NOT the section footer (most stack overflow answers confuse them).

这是我非常简单的代码:

Here's my very simple code:

- (void)viewDidLoad {
    [super viewDidLoad];
    UIView *footerContainer = [[UIView alloc] initWithFrame:CGRectZero];
    footerContainer.backgroundColor=[UIColor greenColor];
    footerContainer.translatesAutoresizingMaskIntoConstraints=NO;
    [footerContainer addConstraints:@[[NSLayoutConstraint
                                       constraintWithItem:footerContainer attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual
                                       toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0f constant:100
                                       ],
                                      [NSLayoutConstraint
                                       constraintWithItem:footerContainer attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual
                                       toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0f constant:[UIScreen mainScreen].bounds.size.width
                                       ]]];

    self.mytableview.tableFooterView=footerContainer;
    [self.view setNeedsLayout];
    [self.view layoutIfNeeded];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return 10;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
    cell.textLabel.text=[NSString stringWithFormat:@"%ld",indexPath.row];
    return cell;
}

然而,结果如下:

正如您所注意到的,页脚显示在桌面视图的顶部。这是一个错误还是我错过了什么?

As you notice, the footer shows on top of the tableview. Is this a bug or am I missing something?

如果我将tableFooterView更改为tableHeaderView,那么它可以正常工作。所以我也期望同样适用于页脚,但事实并非如此。

If I change the tableFooterView to tableHeaderView, then it works fine. So I was expecting the same to work for footer too but it doesn't.

推荐答案

动态大小 UITableView 页眉和页脚视图并不总是与自动布局相配,所以你需要给它一点帮助。

Dynamic-sized UITableView Header and Footer views do not always play nice with auto-layout, so you need to give it a little help.

这是为页脚视图创建简单 UIView 的示例,并添加展开 UILabel (设置为的行数)零)。页脚视图是使用其框架的显式CGRect创建的,并且标签固定到具有自动布局约束的所有四个边。

Here is an example that creates a simple UIView for the footer view and adds an "expanding" UILabel (number of lines set to Zero). The footer view is created with an explicit CGRect for its frame, and the label is pinned to all four sides with auto-layout constraints.

中viewDidLayoutSubviews(),我们告诉自动布局根据对其内容的约束来计算页脚视图的框架,然后我们更新框架值(好吧,特别是高度)。

In viewDidLayoutSubviews(), we tell auto-layout to calculate the frame of the footer view, based on the constraints on its contents, and then we update the frame values (well, specifically the height).

//
// this assumes IBOutlet has been set for "theTableView"
//

- (void)viewDidLoad {
    [super viewDidLoad];

    // standard stuff
    [_theTableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"simpleCell"];
    _theTableView.delegate = self;
    _theTableView.dataSource = self;

    // instantiate a view for the table footer
    // width doesn't matter (it will be stretched to fit the table by default)
    // set height to a big number to avoid a "will attempt to break constraint" warning
    UIView *footerContainer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1, 1000)];

    // give it a color so we can see it
    footerContainer.backgroundColor=[UIColor greenColor];

    // set the footer view
    _theTableView.tableFooterView = footerContainer;


    // instantiate a label to add to the footer view
    UILabel *aLabel = [UILabel new];

    // auto-sizing the height, so set lines to zero
    aLabel.numberOfLines = 0;

    // give it a color so we can see it
    aLabel.backgroundColor = [UIColor yellowColor];

    // set the text to 8 lines for demonstration purposes
    aLabel.text = @"Line 1\nLine 2\nLine 3\nLine 4\nLine 5\nLine 6\nLine 7\nLine 8";

    // standard, for auto-sizing
    aLabel.translatesAutoresizingMaskIntoConstraints = NO;

    // add the label to the footer view
    [footerContainer addSubview:aLabel];

    // constraint the label to 8-pts from each edge...
    [aLabel.topAnchor constraintEqualToAnchor:footerContainer.topAnchor constant:8.0].active = YES;
    [aLabel.leftAnchor constraintEqualToAnchor:footerContainer.leftAnchor constant:8.0].active = YES;
    [aLabel.rightAnchor constraintEqualToAnchor:footerContainer.rightAnchor constant:-8.0].active = YES;
    [aLabel.bottomAnchor constraintEqualToAnchor:footerContainer.bottomAnchor constant:-8.0].active = YES;

}

- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];

    // get a reference to the table's footer view
    UIView *currentFooterView = [_theTableView tableFooterView];

    // if it's a valid reference (the table *does* have a footer view)
    if (currentFooterView) {

        // tell auto-layout to calculate the size based on the footer view's content
        CGFloat newHeight = [currentFooterView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;

        // get the current frame of the footer view
        CGRect currentFrame = currentFooterView.frame;

        // we only want to do this when necessary (otherwise we risk infinite recursion)
        // so... if the calculated height is not the same as the current height
        if (newHeight != currentFrame.size.height) {
            // use the new (calculated) height
            currentFrame.size.height = newHeight;
            currentFooterView.frame = currentFrame;
        }

    }

}

在尝试使自动调整大小的表视图标题视图正常工作时,这也很有用。

This can also be helpful when trying to get auto-sizing table view header views to work properly.

这篇关于UITableView tableFooterView显示在UITableView的顶部 - 错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆