滚动到collectionView的底部不起作用

时间:2017-12-29 11:51:26

标签: ios swift

当视图首次加载其项目时,我尝试滚动到collectionView的底部。我在viewDidLoad中运行此函数:

private func fetchMessages() {
    guard let r = replyTo else { return }
    let urlString = "\(Config.URL)/api/messages/replyTo/\(r)/offset/\(offset)"
    guard let authToken = Auth.getToken() else { return }
    let headers = ["Authorization": "Bearer \(authToken)"]
    Alamofire.request(urlString, headers: headers).responseJSON { (response) in
        guard let value = response.result.value else { return }
        let json = JSON(value)
        for messagesJSON in json["messages"].arrayValue {
            let message = Message(json: messagesJSON.dictionaryObject ?? [:])
            self.messages.append(message)
        }
        self.messages.reverse()
        DispatchQueue.main.async {
            self.collectionView?.reloadData()
            let indexPath = IndexPath(item: self.messages.count - 1, section: 0)
            self.collectionView?.scrollToItem(at: indexPath, at: .bottom, animated: false)
        }
    }
}

我得到最后一个indexPath,然后使用scrollToItem滚动到底部,但它不想滚动到底部。它根本不滚动。除了滚动之外,一切都有效。

2 个答案:

答案 0 :(得分:3)

Taimoor的回答是正确的(本质上)但我想添加一些背景为什么

当整个视图加载到内存中时,会调用

viewDidLoad(),包括所有子视图。但是,此时视图尚未布局,即所有子视图的帧尚未正确设置或换句话说:使用自动布局时,您的约束尚未解决但是当viewDidLoad()被调用时。

因此,集合视图的框架未正确设置,但其大小可能仍为.zero。因此,集合视图无法将任何单元格滚动到其框架中 - 或者至少方法scrollToItem(at:, at:, animated:)会出现意外行为。

您可以确定布局完成的一点是viewDidLayoutSubviews()。但是,请注意,在视图控制器的生命周期内可能会多次调用此方法 - 只要布局中的某些内容发生更改,就会触发另一个布局过程。您可能不希望在发生这种情况时一次又一次地获取数据,因此您需要以某种方式跟踪此情况。

如果你想保持简单,viewDidAppear()也会起作用,因为当视图可见时,它显然已经布局,但用户可能会看到集合视图的滚动/跳转。

viewWillAppear()也可能有用但不保证。

答案 1 :(得分:2)

在元素可视化之前调用

viewDidLoad ,因此无法很好地操作某些UI元素。比如在工作中移动按钮但处理子视图通常不会(比如滚动CollectionView)。

大多数这些操作在viewWillAppear或viewDidAppear中调用时效果最佳。所以尝试在 viewWillAppear viewDidAppear 中执行此操作。