简体   繁体   English

TableView scrollToRow阻止了主ui线程

[英]TableView scrollToRow is blocking the main ui thread

I have a UITableView with about 500 items. 我有一个约500个项目的UITableView

When i call tableView.scrollToRow(at: indexPath, at: .bottom, animated: false) the main UI thread is getting blocked for 3 seconds. 当我调用tableView.scrollToRow(at: indexPath, at: .bottom, animated: false) ,主UI线程被阻塞3秒钟。

Is there a way to fix this? 有没有办法解决这个问题? or is the problem scrolling 500 items? 还是滚动500个项目时出现问题?

Thanks 谢谢


the problem is not with reloadData it was with scrollToRow 问题不在于reloadData ,而在于scrollToRow

From discussion about how to use a table view for chat: We can use a table view which uses a transform to flip the Y coordinate. 从有关如何使用表格视图进行聊天的讨论中:我们可以使用表格视图,该表格视图使用转换来翻转Y坐标。 We then need to do the same for each of the cells so they are not upside down. 然后,我们需要对每个单元进行相同的操作,以使它们不会倒置。

The procedure is to build a normal messaging table view where the newest message is on top (instead of bottom). 该过程是建立一个普通的消息传递表视图,其中最新消息位于顶部(而不是底部)。 Then put the table view on some superview and invert its coordinate system: 然后将表格视图放在某个超级视图上并反转其坐标系:

chatContainer?.transform = CGAffineTransform(scaleX: 1.0, y: -1.0)

The cell containing the messages should also have some sort of superview for all the contents which needs to be flipped: 对于所有需要翻转的内容,包含消息的单元格还应该具有某种超级视图:

    override func awakeFromNib() {
        super.awakeFromNib()

        containerView?.transform = CGAffineTransform(scaleX: 1.0, y: -1.0)
    }

So the cell is basically flipped twice so it is shown correctly. 因此,该单元格基本上翻转了两次,因此可以正确显示。

You may find an example project here . 您可以在此处找到示例项目。

Use time profiler to identify where exactly is the issue. 使用时间分析器来确定问题出在哪里。 The thing is that in general the UITableView performance is not effected by a number of items loaded. 问题是,通常, UITableView性能不受加载的许多项目的影响。 The view itself will load as many items as it needs to fill the whole screen. 视图本身将加载整个屏幕所需的任意数量的项目。

You may test this by logging a method in a cellForRowAtIndexPath . 您可以通过在cellForRowAtIndexPath记录一个方法来进行测试。 So I am guessing this method may be the one that is slow. 因此,我猜想这种方法可能很慢。 Check how you access the data from it, maybe there is some heavy logic on it. 检查如何从中访问数据,也许上面有一些繁琐的逻辑。 Or the cell layout may be bugged and very slow. 否则单元布局可能会出错并且非常缓慢。

In a general case if you have extremely large amount of data consider using core data and NSFetchedResultsController which is designed specifically for this situations. 通常,如果您有大量数据,请考虑使用核心数据和专门为这种情况设计的NSFetchedResultsController But still note that loading 500 elements in a table view should work smoothly without any special optimizations. 但仍需注意,在没有任何特殊优化的情况下,在表视图中加载500个元素应该可以顺利进行。

You should do something like this; 你应该做这样的事情; If user scroll down from top to bottom of the tableview scrollview delegate method fire its "scrollViewDidScroll" method and detect if user bottom of tableview or not then fetch other data and append your array and reload the tableview. 如果用户从表视图的顶部向下滚动到底部,则scrollview委托方法将触发其“ scrollViewDidScroll”方法并检测用户表底部是否存在,然后获取其他数据并追加数组并重新加载表视图。 Thats it! 而已!

- (void)scrollViewDidScroll:(UIScrollView *)scrollView 
{   
    CGFloat actualPosition = scrollView_.contentOffset.y;
    CGFloat contentHeight = scrollView_.contentSize.height - (someArbitraryNumber);
    if (actualPosition >= contentHeight) {
        [self.newsFeedData_ addObjectsFromArray:self.newsFeedData_];
        [self.tableView reloadData];
     }
}

I'm not 100% sure about this solution, didn't had that problem myself. 我不确定这个解决方案100%,我自己也没有遇到这个问题。 Maybe just dispatch it? 也许只是派遣它?

extension UITableView {

func tableViewScrollToBottom(animated: Bool) {

        DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(100)) {

            let numberOfSections = self.numberOfSections
            let numberOfRows = self.numberOfRows(inSection: numberOfSections-1)
            if numberOfRows > 0 {
                let indexPath = IndexPath(row: numberOfRows-1, section: (numberOfSections-1))
                self.scrollToRow(at: indexPath, at: UITableViewScrollPosition.bottom, animated: animated)
            }
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM