如何垂直对齐(居中)UITableView 的内容?

How to vertical align (center) the content of UITableView?

我想将我的 UITableView 的内容居中,其中包含在故事板中创建的 headerViewfooterView,以及 UITableViewCell。我怎样才能做到这一点?

这是我正在尝试实施以解决我的问题,但这不起作用。

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    CGFloat height = self.tableView.frameHeight - self.navigationController.navigationBar.frameHeight - [UIApplication sharedApplication].statusBarFrame.size.height - (self.rowCount * self.rowHeight);
    self.tableView.tableHeaderView.frameHeight = height / 2.0;
}

所以我把navigationBar & statusBar的高度和cells的高度减去tableView的高度,得到空白区域的高度。 现在我得到了空白区域的高度,我将它分成 2 用于页脚和页眉的视图。

像这样设置 UITableView 的框架

CGFloat width = self.view.frame.size.width;
CGFloat height = self.view.frame.size.height;
CGFloat tableHeight = 200.0; //your table height
self.tableView.frame = CGRectMake(0,(height-tableHeight)/2,width,tableHeight);

或者试试这个

在情节提要 TableView 的顶部(UIView 应该是 TableView 的父级)添加一个 UIView。之后设置其约束以填充视图。现在,设置 TableView 的大小并将其约束设置为在顶部垂直和水平方向居中 UIView。这将解决您的问题。

我找到了导致我计算错误的原因。 self.tableView.bounds.size.height的值与viewWillAppear中的实际高度不同。我改用 self.view.bounds.size.height。

viewWillAppeardidRotateFromInterfaceOrientation 函数中:

CGFloat headerHeight = (self.view.frame.size.height - (ROW_HEIGHT * [self.tableView numberOfRowsInSection:0]))) / 2;

self.tableView.contentInset = UIEdgeInsetsMake(headerHeight, 0, -headerHeight, 0);

这将解决您的问题。

编辑

viewWillLayoutSubviews中调用updateTableViewContentInset函数并在每个reloadData之后调用:

目标-C

- (void)updateTableViewContentInset {
    CGFloat viewHeight = self.view.frame.size.height;
    CGFloat tableViewContentHeight = self.tableView.contentSize.height;
    CGFloat marginHeight = (viewHeight - tableViewContentHeight) / 2.0;

    self.tableView.contentInset = UIEdgeInsetsMake(marginHeight, 0, -marginHeight, 0);
}

Swift 4

func updateTableViewContentInset() {
    let viewHeight: CGFloat = view.frame.size.height
    let tableViewContentHeight: CGFloat = tableView.contentSize.height
    let marginHeight: CGFloat = (viewHeight - tableViewContentHeight) / 2.0

    self.tableView.contentInset = UIEdgeInsets(top: marginHeight, left: 0, bottom:  -marginHeight, right: 0)
}

使用 UITableViewcontentSize 属性,这样您就不必考虑单元格 heightcount

- (void) updateTableInsetsForHeight: (CGFloat) height
{
    CGFloat tableViewInset = MAX((height - self.tableView.contentSize.height) / 2.0, 0.f);
    self.tableView.contentInset = UIEdgeInsetsMake(tableViewInset, 0, -tableViewInset, 0);
}

在重新加载 tableView 数据后更新 contentInsets,当 tableView 的包含视图变得可见(viewWillAppear:)并且当它改变大小时(viewWillTransitionToSize:withTransitionCoordinator:).

- (void) viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
    [self updateTableInsetsForHeight: size.height];
}

Swift 3 根据 Pipiks 回答

let headerHeight: CGFloat = (view.frame.size.height - CGFloat(Int(tableView.rowHeight) * tableView.numberOfRows(inSection: 0))) / 2
tableView.contentInset = UIEdgeInsetsMake(headerHeight, 0, -headerHeight, 0)

对于 SWIFT 3 :

var headerHeight: CGFloat = (tableView.frame.size.height - CGFloat(Int(tableView.rowHeight) * tableView.numberOfRows(inSection: 0))) / 2
if headerHeight > 0 {
    tableView.contentInset = UIEdgeInsetsMake(headerHeight, 0, 0/*-headerHeight*/, 0)
} else {
    headerHeight = 0
    tableView.contentInset = UIEdgeInsetsMake(headerHeight, 0, 0/*-headerHeight*/, 0)
}

结果:

覆盖 viewDidLayoutSubviews 并将 table 视图的 frame 与其 contentSize 进行比较以设置其 contentInset。在 Swift 4 中:

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    let tableViewHeight = self.tableView.frame.height
    let contentHeight = self.tableView.contentSize.height

    let centeringInset = (tableViewHeight - contentHeight) / 2.0
    let topInset = max(centeringInset, 0.0)

    self.tableView.contentInset = UIEdgeInsets(top: topInset, left: 0.0, bottom: 0.0, right: 0.0)
}

这适用于自动调整 table 视图单元格