Ios UICollectionView reloadData()不更新集合视图中的单元格
以下是我努力实现的高层次描述; 1.获取数据 2.将提取的数据保存在数组对象中 3.使用数组的大小更新集合视图 这是我的密码Ios UICollectionView reloadData()不更新集合视图中的单元格,ios,swift3,uicollectionview,Ios,Swift3,Uicollectionview,以下是我努力实现的高层次描述; 1.获取数据 2.将提取的数据保存在数组对象中 3.使用数组的大小更新集合视图 这是我的密码 class ItemcollectionViewController:UICollectionViewController, UICollectionViewDelegateFlowLayout { let cellId = "CellId" var categories = [Category]() let viewOptionVar:ViewOption
class ItemcollectionViewController:UICollectionViewController, UICollectionViewDelegateFlowLayout {
let cellId = "CellId"
var categories = [Category]()
let viewOptionVar:ViewOptionBar = {
let vOV = ViewOptionBar()
vOV.translatesAutoresizingMaskIntoConstraints = false
return vOV
}()
private func fetchData() {
let categoryController = CategoryController()
categoryController.getAllCategory(username: "blah", password: "password") {(returnedCategories, error) -> Void in
if error != nil {
print(error)
return
}
self.categories = returnedCategories!
print("size of the array is \(self.categories.count)")
OperationQueue.main.addOperation{self.collectionView?.reloadData()}
}
}
override func viewDidLoad() {
super.viewDidLoad()
fetchData()
collectionView?.backgroundColor = UIColor.white
collectionView?.register(ItemCell.self, forCellWithReuseIdentifier: cellId)
collectionView?.contentInset = UIEdgeInsetsMake(50, 0, self.view.frame.height, self.view.frame.width)
collectionView?.scrollIndicatorInsets = UIEdgeInsetsMake(50, 0, 0, self.view.frame.width)
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
print("in the method \(self.categories.count)")
return self.categories.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! ItemCell
cell.category = categories[indexPath.item]
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 111, height: 111)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 0
}
private func setupViweOptionBar() {
view.addSubview(viewOptionVar)
view.addConstraintsWithFormat(format: "H:|[v0]|", views: viewOptionVar)
view.addConstraintsWithFormat(format: "V:|[v0(50)]", views: viewOptionVar)
}
}
在日志中,我可以看到以下语句:
在方法0中
数组的大小为3
从我的角度看不到任何细胞
有人能告诉我我做错了什么吗?
提前谢谢
编辑1
现在我在注册自定义单元格后获取数据。然而,它仍然不起作用
更新代码:
class ItemcollectionViewController:UICollectionViewController, UICollectionViewDelegateFlowLayout {
let cellId = "CellId"
var categories = [Category]()
let viewOptionVar:ViewOptionBar = {
let vOV = ViewOptionBar()
vOV.translatesAutoresizingMaskIntoConstraints = false
return vOV
}()
private func fetchData() {
let categoryController = CategoryController()
categoryController.getAllCategory(username: "blah", password: "password") {(returnedCategories, error) -> Void in
if error != nil {
print(error)
return
}
self.categories = returnedCategories!
print("size of the array is \(self.categories.count)")
}
}
override func viewDidLoad() {
super.viewDidLoad()
collectionView?.backgroundColor = UIColor.white
collectionView?.register(ItemCell.self, forCellWithReuseIdentifier: cellId)
collectionView?.contentInset = UIEdgeInsetsMake(50, 0, self.view.frame.height, self.view.frame.width)
collectionView?.scrollIndicatorInsets = UIEdgeInsetsMake(50, 0, 0, self.view.frame.width)
collectionView?.dataSource = self
collectionView?.delegate = self
fetchData()
DispatchQueue.main.async{self.collectionView?.reloadData()}
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
print("in the method \(self.categories.count)")
return self.categories.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! ItemCell
cell.category = categories[indexPath.item]
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 111, height: 111)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 0
}
private func setupViweOptionBar() {
view.addSubview(viewOptionVar)
view.addConstraintsWithFormat(format: "H:|[v0]|", views: viewOptionVar)
view.addConstraintsWithFormat(format: "V:|[v0(50)]", views: viewOptionVar)
}
}
编辑2
下面的代码是我的查询方法
func getAllCategory(username:String, password:String, callback: @escaping ([Category]?, String?) -> Void){
var categories = [Category]()
let fetchCategories = URL(string: userURL + "all")
URLSession.shared.dataTask(with: fetchCategories!, completionHandler: { (data, response, error) in
if let err = error {
print(err)
return
}
do {
let jsonCategoryObj = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! [[String: AnyObject]]
for categoryDictionary in jsonCategoryObj {
let category = Category()
category.categoryId = categoryDictionary["categoryId"] as? String
category.categoryName = categoryDictionary["categoryName"] as? String
category.categoryDescription = categoryDictionary["categoryDescription"] as? String
let categoryRegisteredDateString = categoryDictionary["categoryRegisteredDate"] as? String
let df = DateFormatter()
df.dateFormat = self.shapeDateFormat
let categoryRegisteredDate = df.date(from: categoryRegisteredDateString!)!
category.categoryRegisteredDate = categoryRegisteredDate
categories.append(category)
}
callback(categories, nil)
}catch let jsonError {
callback(nil, String(describing: jsonError))
}
}).resume()
}
仅供参考:我知道我没有使用传递的用户凭据,这只是我不同查询方法的复制粘贴错误
DispatchQueue.main.async{self.collectionView?.reloadData()}
collectionView?.backgroundColor = UIColor.white
collectionView?.register(ItemCell.self, forCellWithReuseIdentifier: cellId)
在您注册手机之前,您正在重新加载数据
首先注册单元格、数据源和委托方法,最后重新加载数据
编辑:
我看到你编辑了你的文章
但同样,您甚至在注册手机之前就已经获取了数据。因此,在注册所有单元格、数据源和委托之后,再次移动fetchData方法。我不确定这是如何解决此问题的。但我只是补充了一句
print("size of the array is \(self.categories?.count)")
紧挨着
OperationQueue.main.addOperation{self.collectionView?.reloadData()}
它神奇地工作了。。甚至当我回到屏幕上时,它也没有显示任何东西
我将对此进行更多的调查,并试图找出发生这种情况的原因
更新
使用
DispatchQueue.main.sync
而不是
DispatchQueue.main.async
解决了这个问题 当数据源更改时,重载数据不会更新视图中显示的单元格。重新加载可见项将完成此任务
self.collectionView.reloadData()
self.collectionView.performBatchUpdates({ [weak self] in
let visibleItems = self?.collectionView.indexPathsForVisibleItems ?? []
self?.collectionView.reloadItems(at: visibleItems)
}, completion: { (_) in
})
这是有道理的。但是,即使我将其更改为collectionView?.backgroundColor=UIColor.white collectionView?.registerItemCell.self,forCellWithReuseIdentifier:cellId collectionView?.contentInset=UIEdgeInSectsMake50,0,self.view.frame.height,self.view.frame.width collectionView?.ScrollIndicationSets=UIEdgeInsetsMake50,0,0,self.view.frame.width fetchData DispatchQueue.main.async{self.collectionView?.reloadData}@J.GS.Han您没有设置collectionView.delegate=self和collectionView.datasource=self,我的回答应该说得更清楚,但这是你现在唯一的问题。另外,我认为您需要将UICollectionViewDataSource和UICollectionViewDelegate添加到类中的代码中。谢谢您的回复!我已尝试根据您建议的解决方案更新代码,但效果不佳。我还试图将UICollectionViewDataSource和UICollectionViewDelegate添加到我的类中,但它抱怨说“ItemcollectionViewController”与协议的冗余一致性”UICollectionViewDataSource@J.GS.Han我看到您正在使用UICollectionViewController,那么设置self就是您所需要的,您应该可以开始了。只要确保在更改NumberOfItemsSection方法中的项数时调用reloadData。但是,我无法测试您的代码,因为我没有使用Swift编写代码,但一般来说,除了我为您指出的错误之外,我看不到任何其他错误。我尝试的是将UICollectionViewDataSource和UICollectionViewDelegate添加为我的类的super classesHello。你找到这个问题的解决方案了吗,还是你刚刚给了我我要说的方法?你好。我不知道;我不明白你把那一行放在另一行旁边是什么意思。你是说你把电话排在排队之前了?我希望我早知道,谢谢!