iOS TableView重新加载并滚动顶部

时间:2017-12-29 05:42:24

标签: ios swift uitableview scroll

第二天我无法用表解决问题。

我们有一个segmentedControl,当更改时,会更改表格。 假设控件的段中有3个元素,相应地,3个数组(重要的是,它们的大小不同) 当segmentedControl改变时,我需要向上滚动表。

似乎一切都很简单:contentOffset = .zero和reloadData()

但是。这不起作用,我不知道为什么桌子不能向上滚动。

唯一有效的方法:

UIView.animate (withDuration: 0.1, animations: {
            self.tableView.contentOffset = .zero
        }) {(_) in
            self.tableView.reloadData ()
}

但是现在桌子出现时会出现另一个问题,可能会出现错误,因为segmentedControl已经改变了,而另一个数组中的数据可能没有,我们还没有完成reloadData()

也许我无法理解明显的事情)祝贺即将到来的假期!

6 个答案:

答案 0 :(得分:13)

UItableView方法scrollToRow(at:at:animated:)滚动表视图,直到索引路径标识的行位于屏幕上的特定位置。

使用

tableView.scroll(to: .top, animated: true)

您可以使用我的扩展程序

extension UITableView {

    public func reloadData(_ completion: @escaping ()->()) {
        UIView.animate(withDuration: 0, animations: {
            self.reloadData()
        }, completion:{ _ in
            completion()
        })
    }

    func scroll(to: scrollsTo, animated: Bool) {
        DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(300)) {
            let numberOfSections = self.numberOfSections
            let numberOfRows = self.numberOfRows(inSection: numberOfSections-1)
            switch to{
            case .top:
                if numberOfRows > 0 {
                     let indexPath = IndexPath(row: 0, section: 0)
                     self.scrollToRow(at: indexPath, at: .top, animated: animated)
                }
                break
            case .bottom:
                if numberOfRows > 0 {
                    let indexPath = IndexPath(row: numberOfRows-1, section: (numberOfSections-1))
                    self.scrollToRow(at: indexPath, at: .bottom, animated: animated)
                }
                break
            }
        }
    }

    enum scrollsTo {
        case top,bottom
    }
}

答案 1 :(得分:3)

我找到了更好的方法来做到这一点。它就像一个魅力。

let topIndex = IndexPath(row: 0, section: 0)
tableView.scrollToRow(at: topIndex, at: .top, animated: true)

答案 2 :(得分:1)

你可以使用它。

    tableView.setContentOffset(CGPoint.zero, animated: true)

您可以将动画设置为您的要求

答案 3 :(得分:1)

在调用reloadData

后尝试滚动到顶部后,我收到以下错误
[UITableView _contentOffsetForScrollingToRowAtIndexPath:atScrollPosition:]: row (0) beyond bounds (0) for section (0).'

这为我解决了这个问题:

    tableView.reloadData()
    if tableView.numberOfRows(inSection: 0) != 0 {
        tableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: .top, animated: true)
    }

答案 4 :(得分:1)

好的。因此,人们发现使用

将表格视图滚动到顶部时会遇到问题
public decimal Power(decimal number, decimal raiseToPower)
        {
            decimal result = 0;
            if (raiseToPower < 0)
            {
                raiseToPower *= -1;
                result = 1 / number;
                for (int i = 1; i < raiseToPower; i++)
                {
                    result /= number;
                }
            }
            else
            {
                result = number;
                for (int i = 0; i <= raiseToPower; i++)
                {
                    result *= number;
                }
            }
            return result;
        }

并且需要执行不必要的重新加载数据来解决此问题!

那么self.tableView.setContentOffset(.zero, animated: false) 的问题是iOS的一种错误吗?
最小和最简单的答案是,那么问题是什么?

答案是动态行使用的是setContentOffset。 Tableview将根据行高度以及数据源中包含的行数,节数和行数来计算其内容偏移量。 因此,如果动态高度未正确执行scrollToTop,这是因为它需要重新计算每个行的高度和内容大小。

因此,要从tableview中减少此捆绑包,我们可以提供估算的行高,例如

UITableView.automaticDimension

希望这会对某人有所帮助:)

答案 5 :(得分:1)

通过两次重新加载,完美地回到重新加载页面的顶部

无干扰动画

dataForSource = nil
tableView.reloadData()

DispatchQueue.main.asyncAfter(deadline: .now() + 0.4) {
    self.dataForSource = realData
    self.tableView.reloadData()
}