【问题标题】:When is the UICollectionView done loading completely?UICollectionView 何时完成加载?
【发布时间】:2015-11-01 16:38:06
【问题描述】:

How do I know that the UICollectionView has been loaded completely? 我正在尝试在 Swift 中重现此解决方案,但我无法阅读 Obj-C。有人可以帮忙吗?

【问题讨论】:

标签: swift


【解决方案1】:

如果您想采用您链接的问题的方法,那么:

override func viewDidLoad() {
    super.viewDidLoad()
    self.collectionView?.addObserver(self, forKeyPath: "contentSize", options: NSKeyValueObservingOptions.Old, context: nil)
}

override func observeValueForKeyPath(keyPath: String, ofObject object: AnyObject, change: [NSObject : AnyObject], context: UnsafeMutablePointer<Void>) {
    if let observedObject = object as? UICollectionView where observedObject == self.collectionView {
        print(change)
    }
}

override func viewWillDisappear(animated: Bool) {
    super.viewWillDisappear(animated)
    self.collectionView?.removeObserver(self, forKeyPath: "contentSize")
}

【讨论】:

    【解决方案2】:

    SWIFT 3: @libec 的答案版本

    override func viewDidLoad() {
        super.viewDidLoad()
        collectionView.addObserver(self, forKeyPath: "contentSize", options: NSKeyValueObservingOptions.old, context: nil)
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        collectionView.removeObserver(self, forKeyPath: "contentSize")
    }
    
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        if let observedObject = object as? UICollectionView, observedObject == collectionView {
            print("done loading collectionView")
        }
    }
    

    【讨论】:

    • 字符串“done loading stuff...”后缺少括号
    • 不起作用。每次滚动collectionView时都会调用observeValue,即使contentSize相同。
    【解决方案3】:

    在我的情况下,问题是集合视图没有完全重新加载,所以我们必须等到集合视图“reloadData”完成:

        self.customRecipesCV.reloadData()
    
            DispatchQueue.main.async {
                if let _index = self.selectCustomRecipeAtIndex {
                    let nextIndexpath = IndexPath(row:index, section:0)
                    self.customRecipesCV.scrollToItem(at: nextIndexpath, at: .centeredHorizontally, animated: true)
    
                }
            }
    

    【讨论】:

      【解决方案4】:

      回复晚了,
      在 viewDidAppear 您可以通过以下方式获得它:

      float height = self.myCollectionView.collectionViewLayout.collectionViewContentSize.height;
      

      也许当您重新加载数据然后需要使用新数据计算新高度时,您可以通过以下方式获取它:添加观察者以在您的 CollectionView 在 vi​​ewdidload 完成重新加载数据时进行侦听:

      [self.myCollectionView addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionOld context:NULL];
      

      然后在collectionview重新加载完成后添加波纹管函数以获得新的高度或做任何事情:

      - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary  *)change context:(void *)context
      {
          //Whatever you do here when the reloadData finished
          float newHeight = self.myCollectionView.collectionViewLayout.collectionViewContentSize.height;    
      }
      

      别忘了移除观察者:
      将代码写入viewWillDisappear

      [self.myCollectionView removeObserver:self forKeyPath:@"contentSize" context:NULL];
      


      更多信息请查看答案https://stackoverflow.com/a/28378625/6325474

      【讨论】:

      • viewDidAppear 是一种干净的方法。我喜欢它:)
      【解决方案5】:

      这是我在使用此扩展重新加载集合视图数据时加载指示器的实现。

      extension UICollectionView {
          func reloadData(completion: @escaping ()->()) {
              UIView.animate(withDuration: 0, animations: { self.reloadData() })
              { _ in completion() }
          }
      }
      
      ... somewhere in code ...
      
      collectionView.isHidden = true
      loadingView.startAnimating()
      DispatchQueue.main.async {
          self.collectionView.contentOffset.x = 0
          self.collectionView.reloadData {
              self.loadingView.stopAnimating()
              self.collectionView.isHidden = false
          }
      }
      

      【讨论】:

        【解决方案6】:

        为我工作,没有任何复杂性。

        self.collectionView.reloadData()
            self.collectionView.performBatchUpdates(nil, completion: {
                (result) in
                // ready
            })
        

        当所有操作完成时执行的完成处理程序块。此块采用单个布尔参数,如果所有相关动画都成功完成,则该参数包含值 true;如果它们被中断,则包含值 false。该参数可能为 nil。

        【讨论】:

          【解决方案7】:

          更简单的方法是像这样使用 collectionView 的 performBatchUpdates 函数:

          collectionView?.performBatchUpdates(nil, completion: { _ in
               // collectionView has finished reloading here
          })
          

          【讨论】:

            猜你喜欢
            • 2013-06-21
            • 1970-01-01
            • 2019-05-29
            • 1970-01-01
            • 1970-01-01
            • 2023-03-08
            • 2016-12-26
            • 1970-01-01
            • 2011-07-05
            相关资源
            最近更新 更多