从底部加载UITableView

时间:2012-11-02 13:40:17

标签: iphone ios uitableview ios5

我正在尝试使用UITableView模仿iMessage气泡文本行为。为了始终滚动到底部,我在scrollToRowAtIndexPathviewDidLoad时使用viewDidAppear。这是因为当调用viewDidLoad方法时,表尚未完全加载,因此我需要viewDidAppear中的额外滚动。这段代码就是诀窍。但是,我想要的不是动画滚动(将animated设置为NO无法解决此问题),我希望表格始终从底部显示,而不是加载表格然后转到最后一排。

这可能吗?我找不到任何完全符合预期行为的解决方案。

9 个答案:

答案 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