How to vertical align (center) the content of UITableView?
Override viewDidLayoutSubviews
and compare the tableView's frame
with its contentSize
to set its contentInset
. In 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)
}
This works well with self-sizing table view cells ð
In the viewWillAppear and in the didRotateFromInterfaceOrientation functions :
CGFloat headerHeight = (self.view.frame.size.height - (ROW_HEIGHT * [self.tableView numberOfRowsInSection:0]))) / 2;
self.tableView.contentInset = UIEdgeInsetsMake(headerHeight, 0, -headerHeight, 0);
This will solve your problem.
EDIT
Call the updateTableViewContentInset function in the viewWillLayoutSubviews and after each reloadData :
Ojective-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)
}
Swift 3 based on Pipiks answer
let headerHeight: CGFloat = (view.frame.size.height - CGFloat(Int(tableView.rowHeight) * tableView.numberOfRows(inSection: 0))) / 2
tableView.contentInset = UIEdgeInsetsMake(headerHeight, 0, -headerHeight, 0)
Use the contentSize
property of UITableView
, that how you don't have to take the cell height
or count
into account.
- (void) updateTableInsetsForHeight: (CGFloat) height
{
CGFloat tableViewInset = MAX((height - self.tableView.contentSize.height) / 2.0, 0.f);
self.tableView.contentInset = UIEdgeInsetsMake(tableViewInset, 0, -tableViewInset, 0);
}
Update the contentInsets
after reloading tableView
-data, and when the containing view of the tableView
becomes visible (viewWillAppear:
) and when it changes size (viewWillTransitionToSize:withTransitionCoordinator:
).
- (void) viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
[self updateTableInsetsForHeight: size.height];
}