【问题标题】:UITabelView scrollToRowAtIndexPath scroll to bottom sometimes will made my table disappear, why?UITableView scrollToRowAtIndexPath 滚动到底部有时会让我的表格消失,为什么?
【发布时间】:2017-08-05 17:57:07
【问题描述】:

我希望我的表格视图在第一次进入视图时滚动到底部,但有时不会滚动到底部,有时会使我的表格消失。 (通常发生在第一次或第二次时)。

这是我的滚动代码:

-(void)tableScrollToBottom{

[self.tableView reloadData];

dispatch_async(dispatch_get_main_queue(), ^{
    NSIndexPath* indexPath = [NSIndexPath indexPathForRow: ([self.tableView numberOfRowsInSection:([self.tableView numberOfSections]-1)]-1) inSection: ([self.tableView numberOfSections]-1)];
    [self.tableView scrollToRowAtIndexPath:indexPath
                          atScrollPosition:UITableViewScrollPositionBottom
                                  animated:YES];

});   
}

而且我在 viewDidAppear 中也有 [self tableScrollToBottom],因为如果我只在 viewDidLoad 中滚动表格,表格总是不会滚动到最底部,我不知道为什么,这真的让我很困惑。

我尝试将 [self.tableView layoutIfNeeded] 放在 [self tableScrollToBottom] 中,并删除 dispatch_async,好像我第一次打开应用程序并进入视图仍然无法滚动到最底部,之后第一次,它会正确滚动到底部,我不知道第一次打开应用程序并进入该视图和第一次之后有什么区别。(我的数据来自服务器,它来自以前,并且我的 tableview 行高是动态的)。

这是我现在在 [self tableScrollToBottom] 中的代码:

-(void)tableScrollToBottom {

    [self.tableView layoutIfNeeded];

    NSIndexPath* indexPath = [NSIndexPath indexPathForRow: ([self.tableView numberOfRowsInSection:([self.tableView numberOfSections]-1)]-1) inSection: ([self.tableView numberOfSections]-1)];

    [self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];

}

这里是我调用 [self tableScrollToBottom] 的地方:

-(void)getDicData {

    for (int i = 0; i < _csDictArr.count; i ++) {

        [_chatPersonArray addObject:_csDictArr[i][@"Person"]];
        [_chatDataArray addObject:_csDictArr[i][@"Message"]];
        [_chatDateTimeArr addObject:_csDictArr[i][@"Time"]];                

    }

    [self.tableView reloadData];
    [self tableScrollToBottom];

}

我把[self getDicData]放在ViewDidLoad中,我也在viewDidAppear中调用tableScrollToBottom

-(void)viewDidAppear:(BOOL)animated {

    [self tableScrollToBottom];

}

【问题讨论】:

  • [Self.tableView reloadData] 未包含在 dispatch_async 中,这是否意味着您在后台线程中调用重新加载数据?或者您在主线程上故意/不必要地调用 scrollToRowAtIndexPath ??
  • 对不起,我真的不知道有什么区别 :( 但我尝试将 [Self.tableView reloadData] 放在 dispatch_async 中,现在每次都不会滚动到最底部,有时会让我的桌子也消失了..我真的不知道为什么..
  • 在 [self.tableView reloadData] 处放一个断点;当控制停止时,转到控制台并键入 po [NSThread currentThread] 如果它打印 main 然后你调用 [self.tableView reloadData];已经在主线程中,所以不需要 dispatch_async 否则放 [self.tableView reloadData];也在 dispatch_async 里面
  • 它打印了 {number = 1, name = main},所以这意味着没有必要将 [self tableScrollToBottom] 或 [self.tableView reloadDate] 放入 dispatch_async 中?
  • 不。 Dispatch_async 并指定主线程你告诉iOS在主线程上执行这个闭包内的段但是如果它已经在主线程中没有添加任何值不是它:) 此外,像这样的上下文切换是昂贵的 n 应该小心使用:)

标签: ios objective-c


【解决方案1】:

您应该使用 CATransaction 确保 tableView 在滚动到底部之前完全重新加载。

[CATransaction begin];
[CATransaction setCompletionBlock:^{
        CGFloat yOffset = 0;
        if (self.tableView.contentSize.height > self.tableView.bounds.size.height) {
            yOffset = self.tableView.contentSize.height - self.tableView.bounds.size.height;
        }
        [self.tableView setContentOffset:CGPointMake(0, yOffset) animated:YES];
}];
[self.tableView reloadData];
[CATransaction commit];

【讨论】:

  • 我试图像这样更改代码,但它仍然无法滚动到最底部..
  • 首先,在调用tableScrollToBottom方法之前,确保之前的数据是正确的并且tableView被分配了delegatedatasource。其次,您可以尝试使用viewDidLayoutSubViews,而不是viewDidAppear
  • 注意:viewDidLayoutSubViews 在视图加载或旋转后被多次调用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-07
相关资源
最近更新 更多