33

我在 viewDidLoad 方法中设置页脚视图:

UIView *fView = [[UIView alloc] initWithFrame:CGRectMake(0, 718, 239, 50)];
fView.backgroundColor =[UIColor yellowColor];
self.table.tableFooterView = fView;

不幸的是,页脚没有在(x,y)上面指定的指定中绘制,但它与单元格保持一致,因此如果表格视图有 4 个单元格,页脚将在第 5 个单元格中绘制。

我什至尝试了协议方法,tableView:viewForFooterInSection

- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section{

UIView *fView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 239, 50)];
fView.backgroundColor =[UIColor yellowColor];
    return fView;
}

问题没有解决,我确定tableFooterView属性应该是表格视图底部的页脚视图,但我不确定我可能在这里遗漏了什么?提前谢谢。

4

10 回答 10

54

由于您的目标是让页脚固定在屏幕底部,而不是随表格滚动,因此您不能使用表格视图页脚。事实上,你甚至不能使用UITableViewController.

您必须将视图控制器实现为UIViewController. 然后,您将自己的表格视图添加为子视图。您还可以将页脚添加为视图控制器视图的子视图,而不是表格视图。确保调整表格视图的大小,使其底部位于页脚视图的顶部。

您将需要使您的视图控制器符合UITableViewDataSourceUITableViewDelegate协议,并将所有内容连接起来以复制UITableViewController.

于 2013-03-28T16:46:51.073 回答
34

页脚视图将始终添加到内容的底部。
这意味着节页脚将添加到节的单元格下方,表格页脚视图将添加到所有节的底部 - 无论您在视图中设置的位置如何。

如果您想添加“静态”内容,您应该考虑在表格视图(超级视图)之外添加一个视图 - 如果您使用这是不可能的UITableViewController- 或者您使用[self.table addSubView:view]并将位置/转换调整为表格视图的contentOffset属性scrollViewDidScroll:委托方法(UITableView是的子类,因此UIScrollView您也可以得到它的委托调用),如下代码所示:

@implementation YourTableViewController {
    __weak UIView *_staticView;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    UIView *staticView = [[UIView alloc] initWithFrame:CGRectMake(0, self.tableView.bounds.size.height-50, self.tableView.bounds.size.width, 50)];
    staticView.backgroundColor = [UIColor redColor];
    [self.tableView addSubview:staticView];
    _staticView = staticView;
    self.tableView.contentInset = UIEdgeInsetsMake(0, 0, 50, 0);
}

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    _staticView.transform = CGAffineTransformMakeTranslation(0, scrollView.contentOffset.y);
}

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    // this is needed to prevent cells from being displayed above our static view
    [self.tableView bringSubviewToFront:_staticView];
}

...
于 2013-03-28T16:40:52.893 回答
15

另一种方法是UITableViewController在情节提要中使用,并将其作为容器视图嵌入到 UIViewController 中。然后您可以使用自动布局来设置页脚和包含UITableView

于 2014-12-31T17:23:35.603 回答
9

如果您的表视图或表视图控制器被导航控制器包装,请考虑使用导航控制器的 UIToolbar。它会一直粘在底部。

[self.navigationController setToolbarHidden:NO];
于 2015-11-21T14:46:08.010 回答
4

看起来类似于下面的东西效果很好:

import PlaygroundSupport
import UIKit

let testVC = UITableViewController(style: .grouped)
testVC.view.frame = CGRect(x: 0, y: 0, width: 400, height: 700)
testVC.view.backgroundColor = .white

class TableViewDataSourceDelegate : NSObject {
    var rows = 2
}

extension TableViewDataSourceDelegate : UITableViewDataSource, UITableViewDelegate {

    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return rows
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell(style: .default, reuseIdentifier: nil)
        cell.backgroundColor = .red
        return cell
    }

    func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {

        let tableViewHeight = tableView.bounds.size.height
        let varticalMargin: CGFloat
        if #available(iOS 11.0, *) {
            varticalMargin = tableView.directionalLayoutMargins.bottom + tableView.directionalLayoutMargins.top
        } else {
            varticalMargin = tableView.layoutMargins.bottom + tableView.layoutMargins.top
        }

        let verticalInset: CGFloat
        if #available(iOS 11.0, *) {
            verticalInset = tableView.adjustedContentInset.bottom + tableView.adjustedContentInset.top
        } else {
            verticalInset = tableView.contentInset.bottom + tableView.contentInset.top
        }
        let tableViewContentHeight = tableView.contentSize.height - varticalMargin


        let height: CGFloat
        if #available(iOS 11.0, *) {
            let verticalSafeAreaInset = tableView.safeAreaInsets.bottom + tableView.safeAreaInsets.top
            height = tableViewHeight - tableViewContentHeight - verticalInset - verticalSafeAreaInset
        } else {
            height = tableViewHeight - tableViewContentHeight - verticalInset
        }

        if (height < 0) {
            return 0
        } else {
            return height
        }
    }

    func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
        let extraButtonSpace = UIView()
        extraButtonSpace.backgroundColor = .clear
        return extraButtonSpace
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        if indexPath.row == 0 {
            tableView.beginUpdates()
            rows += 1
            tableView.insertRows(at: [indexPath], with: .automatic)
            tableView.endUpdates()
        } else if indexPath.row == 1 {
            tableView.beginUpdates()
            rows -= 1
            tableView.deleteRows(at: [indexPath], with: .automatic)
            tableView.endUpdates()
        } else {
            tableView.beginUpdates()
            tableView.endUpdates()
        }
    }
}


let controller = TableViewDataSourceDelegate()
testVC.tableView.delegate = controller
testVC.tableView.dataSource = controller
testVC.tableView.reloadData()

let extraButtonSpace = UIView(frame: CGRect(x: 0, y: 0, width: 400, height: 80))
extraButtonSpace.backgroundColor = .yellow
testVC.tableView.tableFooterView = extraButtonSpace

PlaygroundPage.current.liveView = testVC.view

操场上的屏幕

于 2017-10-24T16:26:38.413 回答
3

我能够将标签固定到我的静态 UITableViewController 的底部。不是所有场景的完美解决方案,但可以满足我的简单需求。

UIView* v = [[UIView alloc] initWithFrame:self.view.bounds];
CGFloat labelHeight = 30;
CGFloat padding = 5;
UILabel* l = [[UILabel alloc] initWithFrame:CGRectMake(0, v.frame.size.height - labelHeight - padding, self.view.frame.size.width, labelHeight)];
l.text = @"Hello World";
[v addSubview:l];
[self.tableView setBackgroundView:v];
于 2016-08-08T05:54:55.397 回答
1

如果要使页脚固定在底部,则应创建自定义页脚视图并在 tableView 内容大小发生变化时更改页脚框架:

-(void)changeCustomTableFooterYPositionWithTableFrame:(CGRect)tableFrame tableContentSize: (CGSize) tableContentSize {
    CGFloat originalTableViewTopEdgeInset = self.tableView.contentInset.top;
    CGFloat originalTableViewBottomEdgeInset = self.tableView.contentInset.bottom - self.tableFooterView.frame.size.height;

    CGFloat footerViewYPositionByContentSize = tableContentSize.height;
    CGFloat footerViewYPositionByTableSize = tableFrame.size.height - self.tableFooterView.frame.size.height - originalTableViewTopEdgeInset - originalTableViewBottomEdgeInset;
    CGFloat tableFooterViewYPosition = MAX(footerViewYPositionByContentSize, footerViewYPositionByTableSize);

    self.tableFooterView.frame = CGRectMake(self.tableFooterView.frame.origin.x, tableFooterViewYPosition, self.customTableFooterView.frame.size.width, self.customTableFooterView.frame.size.height);
}

要检测 contentSize 何时更改,请将观察者添加到 contentSize:

 [self addObserver: self forKeyPath: @"tableView.contentSize" options: NSKeyValueObservingOptionNew + NSKeyValueObservingOptionOld context: ContentSizeContext];

插入页脚时不要忘记更改 tableView.edgeInsets:

self.tableView.contentInset = UIEdgeInsetsMake(self.tableView.contentInset.top, self.tableView.contentInset.left, self.tableView.contentInset.bottom + self.customTableFooterView.frame.size.height, self.tableView.contentInset.right);

您可以在下面的链接中看到继承的类和示例: TableViewWithFooterAtBottom

于 2017-10-18T11:44:56.047 回答
0

您可以使用它根据您拥有的行数使表格看起来更小:

    let tblView =  UIView(frame: CGRectZero)
    tableView.tableFooterView = tblView
    tableView.tableFooterView!.hidden = true
    tableView.backgroundColor = UIColor.clearColor()

另一种选择是仅根据您遇到该问题的最小行数来更改索引路径处行的高度。

于 2016-02-16T15:38:39.350 回答
0

以下是此页脚问题的解决方案,当我们不希望页脚一直粘在底部时,AKA。只有当没有足够的行来填满屏幕,或者当用户一直向下滚动屏幕时,它才会停留在底部。

将您的作为子视图添加self.footerView到您self.tableView的子视图-viewDidLoad:或类似的地方,然后设置委托self.tableView,将 tableview 的内容插入更新为self.tableView.contentInset = UIEdgeInsetsMake(0, 0, CGRectGetHeight(self.footerView), 0);并设置以下方法:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
  [self updateFooterView];
}

- (void)updateFooterView
{
  CGRect sectionFrame = [self.tableView rectForSection:0];
  CGFloat bottomSpace = self.tableView.contentOffset.y + CGRectGetHeight(self.tableView.frame) - CGRectGetMaxY(sectionFrame);
  CGFloat footerHeight = CGRectGetHeight(self.footerView.frame);
  CGFloat transformY = self.tableView.contentOffset.y + footerHeight - MIN(bottomSpace,footerHeight);

  CGRect footerFrame = self.footerView.frame;
  footerFrame.origin.y = self.tableView.bounds.size.height - footerFrame.size.height + transformY;
  self.footerView.frame = footerFrame;
}

每当您需要更新页脚(即添加新行后)时,只需调用-updateFooterView即可

于 2017-01-23T22:21:23.793 回答
-1

我对这个解决方案并不感到非常自豪,但它对我来说到目前为止只使用 IB。如果对您有用,它将使用您的 UITableViewController 的工具栏区域。

  1. 创建一个新的临时 UIViewController
  2. 将 Toolbar 拖入此 UIViewController
  3. 在此工具栏上拖动一个 UIView。为此,我使用了左侧的元素树,这更容易。这将创建一个您将在步骤 5 中移动的 BarButtonItem。
  4. 在您的 UITableViewController 上拖动一个 BarButtonItem,这将创建一个工具栏项目部分。
  5. 将在步骤 3 中创建的 BarButtonItem 拖到在步骤 4 中创建的工具栏项目部分。
  6. 删除 UIViewController 并根据需要编辑 BarButtonItem。
于 2019-02-12T18:22:58.673 回答