9

我正在尝试使用UITableView. 为了始终滚动到底部,我使用了scrollToRowAtIndexPathwhenviewDidLoadviewDidAppear. 这是因为在viewDidLoad调用该方法时,表格还没有完全加载,所以我需要在viewDidAppear. 这段代码成功了。但是,我想要的不是动画滚动(设置animatedNO不能解决此问题),我希望表格始终从底部显示,而不是加载表格然后转到最后一行。

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

4

9 回答 9

27

这是最好的解决方案!

只是扭转一切!

tableView.transform = CGAffineTransformMakeRotation(-M_PI);
cell.transform = CGAffineTransformMakeRotation(M_PI);

斯威夫特 4.0:

tableView.transform = CGAffineTransform(rotationAngle: -CGFloat.pi)
cell.transform = CGAffineTransform(rotationAngle: CGFloat.pi)

不过要小心,因为现在 headerView 和 footerView 的位置也颠倒了。

于 2016-04-21T07:09:32.270 回答
9

您可以避免来自 viewDidLoad 的调用,因为从 viewDidAppear 中滚动会使第一次调用变得多余。每次导航回视图时都会调用 viewDidAppear,但视图初始化时只会调用一次 viewDidLoad。

我同意先前的建议,即向用户隐藏滚动而不是更改 UITableView 加载数据的方式。我的建议是在 viewWillAppear 方法中使用 scrollToRowAtIndexPath 方法,并将动画设置为 NO。之后,如果您必须在表格对用户可见时添加新行,请使用 insertRowsAtIndexPaths:withRowAnimation: 在表格视图底部添加一行。请务必注意在数据模型的末尾添加数据,以便当用户离开并返回时,他/她会回到相同的布局。

希望这可以帮助。

编辑:刚刚看到您不接受先前答案的原因,并认为我会再详细说明一下。我提出的解决方案需要最少的努力,避免一次又一次地调用 reloadData ,从而避免一次又一次地调用 scrollToRowAtIndexPath 方法。您只需要在 viewWillAppear 中调用一次 scrollToRowAtIndexPath 即可滚动到表格视图的底部(这样做时向用户隐藏转换),您无需再次这样做。

于 2012-12-11T13:48:28.980 回答
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 函数,这样我就留在了表的底部。

于 2012-12-12T13:54:03.190 回答
2

您可以将您的UITableView隐藏打开viewDidLoad,然后在viewDidAppear将表格滚动到底部后立即将其更改为可见。这样用户就不会看到滚动动画。

于 2012-11-02T14:04:18.790 回答
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它将在用户看到表格之前完成。

于 2012-12-13T10:28:45.177 回答
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];
}

如果您需要更多帮助,请告诉我。

于 2012-12-11T12:22:28.310 回答
0
scrollToRowAtIndexPath

用于将 tableview 中的行滚动到特定位置

于 2012-11-02T14:24:11.153 回答
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)];
于 2016-08-12T12:23:28.833 回答
0

斯威夫特 3.1

tableView.transform = CGAffineTransform(rotationAngle: CGFloat.pi)
cell.transform = CGAffineTransform(rotationAngle: CGFloat.pi)

致谢:@Christos Hadjikyriacou

于 2017-09-18T14:50:39.877 回答