【问题标题】:Load UITableView from the bottom从底部加载 UITableView
【发布时间】:2012-10-23 04:20:12
【问题描述】:

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

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

【问题讨论】:

  • 您可以尝试将表格视图翻转 180° ,将自定义表格视图单元格翻转 180° 以使其看起来正常并反转您的索引路径逻辑。您的表格视图底部会有第 0 行。
  • 这似乎是一项非常艰巨的工作。只需反转您的数据源,将最后一个对象切换为第一个对象,依此类推。然后你会以相反的顺序显示它。
  • @Martol1ni 只有两行代码!
  • 反转你的数据源数组怎么样?!?
  • @Lefteris 反转我的数据源数组将强制滚动从下到上?如果没有,我不能使用这个解决方案。

标签: iphone ios uitableview ios5


【解决方案1】:

这是最好的解决方案!

一切都颠倒过来!

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 的位置也颠倒了。

【讨论】:

  • 这是有史以来最好的答案!和他妈的容易!
  • 这是一个 hacky 解决方案,如果您需要向单元格添加任何类型的滑动手势/动作,将会导致问题。
  • 使用 -M_PI 似乎将滚动指示器放在左侧。使用 self.tableView.transform = CGAffineTransformMakeScale(1, -1);将滚动指示器保持在右侧
  • 太棒了!不同意滑动评论,因为您也可以旋转文本!
【解决方案2】:

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

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

希望这会有所帮助。

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

【讨论】:

  • 我接受这个答案是因为@NumanTariq 是第一个指出应该在viewWillAppear 中完成刷新的人。
  • 但是在滚动之前,我们需要放置 reloadData 方法,导致动画闪烁效果出现。如何解决第一次进入屏幕并将数据添加到数组和加载表并滚动到底部而没有任何闪烁效果。
【解决方案3】:

我在自己构建的 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 函数,这样我就留在了表的底部。

【讨论】:

    【解决方案4】:

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

    【讨论】:

      【解决方案5】:

      解决方案是覆盖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 执行此操作,它将在用户看到表格之前完成。

      【讨论】:

        【解决方案6】:

        您可以通过制作一个不可见的页脚并在其中进行计算来修复它。加载页脚时, 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];
        }
        

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

        【讨论】:

          【解决方案7】:
          scrollToRowAtIndexPath
          

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

          【讨论】:

            【解决方案8】:

            如果高度小于父视图,只需在加载数据后更改内容插入以移动表格视图的内容视图。

            [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)];
            

            【讨论】:

              【解决方案9】:

              斯威夫特 3.1

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

              致谢:@Christos Hadjikyriacou

              【讨论】:

              • 最好还是那样做cell.contentView.transform = CGAffineTransform(rotationAngle: CGFloat(Double.pi))
              猜你喜欢
              • 2015-08-01
              • 2016-04-07
              • 2017-07-16
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2016-10-18
              • 1970-01-01
              • 2012-08-06
              相关资源
              最近更新 更多