Swift数组追加不适用于collectionView重新加载数据
Posted
技术标签:
【中文标题】Swift数组追加不适用于collectionView重新加载数据【英文标题】:Swift array append not working on collectionView reload data 【发布时间】:2018-08-03 13:08:41 【问题描述】:在我的 collectionView 单元格中,我有一个嵌套的集合视图。它在进行 api 调用 (didSet) 后首先更新,但是当我尝试将数据附加到数据源数组并重新加载 collectionView 时,在加载更多机制中。更改不会反映。这是我的代码
class PhotosCollectionViewController:
UICollectionViewCell,UICollectionViewDelegate,
UICollectionViewDataSource, UICollectionViewDelegateFlowLayout
let network = networkingService()
let keychain = KeychainSwift()
var userID: String?
var code: String?
var platesID: String!
didSet
let parameters: Parameters = ["code": code!, "userID": userID!,
"plateID": platesID!]
network.makeGetRequestDecodable(parameters: parameters, url:
"endpoint") (reponse) in
do
let modeled = try JSONDecoder().decode([gps_sing].self, from:reponse)
self.gps_singleton_posts = modeled
print("Reload Method Called")
self.appsCollectionView?.reloadData()
catch let err
print(err)
var gps_singleton_posts: [gps_sing]?
let gridId = "gridID"
var appsCollectionView: UICollectionView? =
let layout = UICollectionViewFlowLayout()
layout.minimumInteritemSpacing = 0
layout.minimumLineSpacing = 3
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
collectionView.backgroundColor = UIColor.white
collectionView.translatesAutoresizingMaskIntoConstraints = false
return collectionView
()
override init(frame: CGRect)
super.init(frame: frame)
if let value = keychain.get("userID")
self.userID = value
// print("keychain\(self.userID!)")
if let value = keychain.get("security_token")
self.code = value
// print("keychain\(self.code!)")
appsCollectionView?.dataSource = self
appsCollectionView?.delegate = self
appsCollectionView?.contentInset = UIEdgeInsetsMake(60, 0, 0, 0)
appsCollectionView?.scrollIndicatorInsets = UIEdgeInsetsMake(60,
0, 0, 0)
addSubview(appsCollectionView!);
addConstraintsWithFormat("H:|[v0]|", views: appsCollectionView!)
addConstraintsWithFormat("V:|[v0]|", views: appsCollectionView!)
appsCollectionView?.register(ImageCell.self,
forCellWithReuseIdentifier: gridId)
required init?(coder aDecoder: NSCoder)
fatalError("init(coder:) has not been implemented")
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
return CGSize(width: 123, height: 123)
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
print(gps_singleton_posts)
if let count = gps_singleton_posts?.count
return count
return 0
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
let parameters: Parameters = ["code": code!, "userID": userID!,
"plateID": platesID!,"token":"loadScroll","lim":gps_singleton_posts!
[(gps_singleton_posts!.count)-1].id!]
network.makeGetRequestDecodable(parameters: parameters, url: "get/getGridPS.php") (reponse) in
do
let modeled = try JSONDecoder().decode([gps_sing].self, from:reponse)
for model in modeled
self.gps_singleton_posts?.append(model)
print("Reload Method Called")
collectionView.reloadData()
print(self.gps_singleton_posts)
catch let err
print(err)
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
print(self.gps_singleton_posts?.count)
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: gridId, for: indexPath)
as! ImageCell
cell.backgroundColor = UIColor.red
cell.singlePost = gps_singleton_posts![indexPath.row]
return cell
func scrollViewDidScroll(_ scrollView: UIScrollView)
scrollView.isScrollEnabled = false
class ImageCell: UICollectionViewCell
var imageViewGrid: UIImageView =
let imageView = UIImageView()
imageView.contentMode = .scaleAspectFill
imageView.frame = CGRect(x: 0, y:0 , width: 100, height: 100)
imageView.image = UIImage(named: "delete")
imageView.clipsToBounds = true
imageView.translatesAutoresizingMaskIntoConstraints = false
return imageView
()
var textLabel: UILabel =
let lv = UILabel()
lv.textColor = UIColor.red
lv.translatesAutoresizingMaskIntoConstraints = false
return lv
()
var singlePost: gps_sing!
didSet
let imageUrl = singlePost.uid
print(imageUrl!)
imageViewGrid.setImageWith(NSURL(string: imageUrl!)! as URL)
override init(frame: CGRect)
super.init(frame: frame)
setUpViews()
func setUpViews()
addSubview(imageViewGrid)
addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[v0]|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0": imageViewGrid]))
addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[v0]|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0": imageViewGrid]))
required init?(coder aDecoder: NSCoder)
fatalError("init(coder:) has not been implemented")
在上面的代码中 (didSelectAt) 函数用于加载更多的项目..但没有反映更改。请帮帮我。非常感谢您回答我的问题。
【问题讨论】:
【参考方案1】:所以,我找到了解决问题的方法。在上面的集合视图中,我禁用了滚动..因为重新加载数据后添加的内容没有显示出来。一旦我启用滚动数据开始显示。
【讨论】:
【参考方案2】:首先:切勿在并行线程中更改布局。
我在 platesID 的didSet
中看到您正在执行 API 调用,并且在其响应中您正在尝试重新加载集合视图。这种操作必须在主线程中完成!尝试用这种方式包装collectionview.reloadData()
DispatchQueue.main.async [weak self] in
self?.appsCollectionView?.reloadData()
我不知道这是否能解决您的所有问题,但 reloadData() 操作可能无法在辅助线程中正常工作。
布局操作必须始终在主线程上启动。
【讨论】:
您好,感谢您的回答!将尝试并回复您 刚刚试了一下...没用 :( 还有什么我能做的吗?以上是关于Swift数组追加不适用于collectionView重新加载数据的主要内容,如果未能解决你的问题,请参考以下文章