There are one to three UITableViewCell
s in a UITableViewView
. Is there a way to always position the cell(s) at the bottom of screen after rel
I would resize and re-position the UITableView in its parent view depending on the number of cells. I guess it's the solution that involves minimum workarounds. Also, do you really need to use a UITableView?
Elegant and quick solution without a line of code.
Use container view and put UITableViewController into container( embed segue ).
You can set any height you want to this container.
USE THIS. Surely this will help.
- (void)reloadData
{
[super reloadData];
[self recalculateContentInset];
[self recalculateScrollIndicator];
}
- (void)recalculateContentInset
{
CGFloat contentInsetHeight = MAX(self.frame.size.height - self.contentSize.height, 0);
CGFloat duration = 0.0;
[UIView animateWithDuration:duration
delay:0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
[self setContentInset:UIEdgeInsetsMake(contentInsetHeight, 0, 0, 0)];
}completion:nil];
}
- (void)recalculateScrollIndicator
{
if(self.contentSize.height >= self.frame.size.height){
[self setShowsVerticalScrollIndicator:YES];
} else {
[self setShowsVerticalScrollIndicator:NO];
}
}
I've create a new sample solution since the previous answer is not outdated for modern use.
The latest technique uses autolayout and self-sizing cells so the previous answer would no longer work. I reworked the solution to work with the modern features and created a sample project to put on GitHub.
Instead of counting up the height of each row, which is causes additional work, this code instead gets the frame for the last row so that the content inset from the top can be calculated. It leverages what the table view is already doing so no additional work is necessary.
This code also only sets the top inset in case the bottom inset is set for the keyboard or another overlay.
Please report any bugs or submit improvements on GitHub and I will update this sample.
GitHub: https://github.com/brennanMKE/BottomTable
- (void)updateContentInsetForTableView:(UITableView *)tableView animated:(BOOL)animated {
NSUInteger lastRow = [self tableView:tableView numberOfRowsInSection:0];
NSUInteger lastIndex = lastRow > 0 ? lastRow - 1 : 0;
NSIndexPath *lastIndexPath = [NSIndexPath indexPathForItem:lastIndex inSection:0];
CGRect lastCellFrame = [self.tableView rectForRowAtIndexPath:lastIndexPath];
// top inset = table view height - top position of last cell - last cell height
CGFloat topInset = MAX(CGRectGetHeight(self.tableView.frame) - lastCellFrame.origin.y - CGRectGetHeight(lastCellFrame), 0);
UIEdgeInsets contentInset = tableView.contentInset;
contentInset.top = topInset;
UIViewAnimationOptions options = UIViewAnimationOptionBeginFromCurrentState;
[UIView animateWithDuration:animated ? 0.25 : 0.0 delay:0.0 options:options animations:^{
tableView.contentInset = contentInset;
} completion:^(BOOL finished) {
}];
}
Add a blank cell in a new section and make it the section at index zero.
-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView
{
return 2;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (section==0)
{
return 1;
}
return [self.yourArray count];
}
Now in
tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath //method add following in beginnig//
if (indexPath.section == 0 )
{
UITableViewCell * cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
// cell.backgroundColor = [UIColor clearColor];
return cell;
}
Now
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 0 )
{
if (self.yourArray.count>0)
{
CGFloat totalCellHeight = self.messages.count * yourCellHeight;
if (totalCellHeight>= self.table.bounds.size.height)
{
return 0;
}
return self.table.bounds.size.height - totalCellHeight;
}
else
return self.table.bounds.size.height;
}
return yourCellHeight;
}
Now paste this where you are reloading the tableView
[self.table reloadData];
[self.table scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:[self.yourArray count]-1 inSection:1] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
It worked for me. Hope this helps.
All answers got some quirks with dynamic rowHeight and/or animations. For me the best working solution was a transformation of the table (flipY):
tableView.transform = CGAffineTransform (scaleX: 1,y: -1)
inside cellForRowAt
:
cell.contentView.transform = CGAffineTransform (scaleX: 1,y: -1)
cell.accessoryView?.transform = CGAffineTransform (scaleX: 1,y: -1)
You may also reverse your data-array and may also flip section-header/footer. Also your footer becomes your new header - but hey, it works.