【发布时间】:2015-11-01 16:38:06
【问题描述】:
How do I know that the UICollectionView has been loaded completely? 我正在尝试在 Swift 中重现此解决方案,但我无法阅读 Obj-C。有人可以帮忙吗?
【问题讨论】:
-
这是可靠的解决方案:stackoverflow.com/a/39798079
标签: swift
How do I know that the UICollectionView has been loaded completely? 我正在尝试在 Swift 中重现此解决方案,但我无法阅读 Obj-C。有人可以帮忙吗?
【问题讨论】:
标签: swift
如果您想采用您链接的问题的方法,那么:
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")
}
【讨论】:
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")
}
}
【讨论】:
在我的情况下,问题是集合视图没有完全重新加载,所以我们必须等到集合视图“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)
}
}
【讨论】:
回复晚了,
在 viewDidAppear 您可以通过以下方式获得它:
float height = self.myCollectionView.collectionViewLayout.collectionViewContentSize.height;
也许当您重新加载数据然后需要使用新数据计算新高度时,您可以通过以下方式获取它:添加观察者以在您的 CollectionView 在 viewdidload 完成重新加载数据时进行侦听:
[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];
【讨论】:
这是我在使用此扩展重新加载集合视图数据时加载指示器的实现。
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
}
}
【讨论】:
为我工作,没有任何复杂性。
self.collectionView.reloadData()
self.collectionView.performBatchUpdates(nil, completion: {
(result) in
// ready
})
当所有操作完成时执行的完成处理程序块。此块采用单个布尔参数,如果所有相关动画都成功完成,则该参数包含值 true;如果它们被中断,则包含值 false。该参数可能为 nil。
【讨论】:
更简单的方法是像这样使用 collectionView 的 performBatchUpdates 函数:
collectionView?.performBatchUpdates(nil, completion: { _ in
// collectionView has finished reloading here
})
【讨论】: