我正在尝试使用UITableView
模仿iMessage气泡文本行为。为了始终滚动到底部,我在scrollToRowAtIndexPath
和viewDidLoad
时使用viewDidAppear
。这是因为当调用viewDidLoad
方法时,表尚未完全加载,因此我需要viewDidAppear
中的额外滚动。这段代码就是诀窍。但是,我想要的不是动画滚动(将animated
设置为NO
无法解决此问题),我希望表格始终从底部显示,而不是加载表格然后转到最后一排。
这可能吗?我找不到任何完全符合预期行为的解决方案。
答案 0 :(得分:21)
这是最好的解决方案!
只需扭转一切!
tableView.transform = CGAffineTransformMakeRotation(-M_PI);
cell.transform = CGAffineTransformMakeRotation(M_PI);
Swift 4.0:
tableView.transform = CGAffineTransform(rotationAngle: -CGFloat.pi)
cell.transform = CGAffineTransform(rotationAngle: CGFloat.pi)
但要小心,因为现在headerView和footerView的位置也是相反的。
答案 1 :(得分:9)
您可以避免来自viewDidLoad的调用,因为从viewDidAppear中滚动会使第一次调用变为冗余。每次导航回视图时都会调用viewDidAppear,但只在初始化视图时调用viewDidLoad一次。
我同意早先从用户隐藏滚动的建议,而不是改变UITableView加载数据的方式。我的建议是在viewWillAppear方法中使用scrollToRowAtIndexPath方法,并将动画设置为NO。之后,如果您必须在表对用户可见时添加新行,请使用insertRowsAtIndexPaths:withRowAnimation:在表视图的底部添加一行。一定要注意在数据模型的末尾添加数据,这样当用户导航并返回时,他/她会回到相同的布局。
希望这有帮助。
编辑: 刚刚看到你不接受以前的答案的理由,并认为我会详细说明一点。我建议的解决方案需要尽可能少的工作,避免一次又一次地调用reloadData,从而避免一次又一次地调用scrollToRowAtIndexPath方法。您只需要在viewWillAppear中调用scrollToRowAtIndexPath来滚动到表视图的底部(这样做时隐藏了用户的转换),您不需要再次这样做。
答案 2 :(得分:4)
我在我建立的RPN计算器中做了类似的事情。我有一个包含所有数字的表视图,当一个数字被添加到堆栈中时,所有内容都弹出一个单元格。当我加载视图时,我调用:
[self.myTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:NumOfStackItems - 1 inSection:0]
atScrollPosition:UITableViewScrollPositionTop animated:NO];
在我的视图中看到了。这样我的表视图开始显示在堆栈的底部,没有看到动画。通过将它放在viewWillAppear中,每次我导航到视图时,它都显示在表格的底部。
当我向堆栈添加数字时,我只是将它添加到一个包含所有数字的数组中,然后将文本放在正确的行中,如下所示:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Cell initialization here...
NSUInteger row_num = [indexPath row];
cell.rowNumber.text = [NSString stringWithFormat:@"%g", [DataArray objectAtIndex:NumberOfStackItems-row_num-1];// subtract the row number off to get the correct array index
return cell
}
我还确保每当我使用新值更新tableview时,我首先调用reloadData函数,然后调用上面引用的scrollToRowAtIndexPath函数,这样我就停留在表的底部。
答案 3 :(得分:2)
解决方法是覆盖viewWillAppear
并让它滚动(非动画)到底部:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self goToBottom];
}
-(void)goToBottom
{
NSIndexPath *lastIndexPath = [self lastIndexPath];
[self.tableView scrollToRowAtIndexPath:lastIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:NO];
}
-(NSIndexPath *)lastIndexPath
{
NSInteger lastSectionIndex = MAX(0, [self.tableView numberOfSections] - 1);
NSInteger lastRowIndex = MAX(0, [self.tableView numberOfRowsInSection:lastSectionIndex] - 1);
return [NSIndexPath indexPathForRow:lastRowIndex inSection:lastSectionIndex];
}
通过viewWillAppear
执行此操作,将在用户查看表格之前完成。
答案 4 :(得分:1)
您可以将UITableView
隐藏在viewDidLoad
上,然后在将表格滚动到底部后立即将其更改为viewDidAppear
上的可见内容。这样用户就不会看到滚动动画。
答案 5 :(得分:1)
你可以通过制作一个不可见的页脚来修复它并在那里进行计算。加载页脚时,将更新contentSize。为了使其滚动,我检查设置tableview的contentOffset。
我已经注释掉了动画部分,因为你想要它没有,但它也有效。
-(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
return 1;
}
-(UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
if( tableView.contentOffset.y != tableView.contentSize.height - tableView.frame.size.height && automaticScroll ){
//[UIView animateWithDuration:0.0 animations:^{
self.contentTableView.contentOffset = CGPointMake(0, tableView.contentSize.height - self.contentTableView.frame.size.height);
//} completion:^(BOOL finished) {
[tableView reloadData];
//}];
automaticScroll = NO;
}
UIView *emptyFooter = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 1)];
emptyFooter.backgroundColor = [UIColor clearColor];
return emptyFooter;
}
我创建了一个BOOL automaticScroll来触发滚动到底部。这应该在viewWillAppear方法中设置,或者在加载数据并重新加载tableView时设置。
如果要添加行,还需要设置BOOL,如:
-(void)addItemButtonClicked:(id)sender
{
automaticScroll = YES;
//Add object to data
[self.contentTableView reloadData];
}
如果您需要更多帮助,请告诉我。
答案 6 :(得分:0)
scrollToRowAtIndexPath
用于将tableview中的行滚动到特定位置
答案 7 :(得分:0)
如果高度小于父视图,只需在加载数据后更改内容插入以移动表视图的内容视图。
[self.tableView reloadData];
[self.tableView setContentInset:UIEdgeInsetsMake(self.view.frame.size.height - self.tableView.contentSize.height < 0 ? 0 : self.view.frame.size.height - self.tableView.contentSize.height, 0, 0, 0)];
答案 8 :(得分:0)
Swift 3.1
tableView.transform = CGAffineTransform(rotationAngle: CGFloat.pi)
cell.transform = CGAffineTransform(rotationAngle: CGFloat.pi)
致谢:@Christos Hadjikyriacou