当我迅速从该视图控制器移动时,为啥我的 Collectionview 单元格没有显示?
Posted
技术标签:
【中文标题】当我迅速从该视图控制器移动时,为啥我的 Collectionview 单元格没有显示?【英文标题】:Why my Collectionview cells are not showing when i move from that viewcontroller in swift?当我迅速从该视图控制器移动时,为什么我的 Collectionview 单元格没有显示? 【发布时间】:2021-04-04 07:08:46 【问题描述】:我能够解析 JSON 并在 Collectionview 中添加单元格.. 但是如果我从这个 Viewcontroller 移动到 viewcontroller 则 collectionview 不会显示.. 但在 JSON 中添加数据
添加collectionview和JSON解析的代码:
class ImageItemModel
var title: String?
var profileImage: UIImage?
var pic_id: Double?
init(title: String?, imgTitle: UIImage?, pic_id: Double?)
self.title = title
self.profileImage = imgTitle
self.pic_id = pic_id
class EditProfileImageViewController: UIViewController
@IBOutlet weak var titleTextfield: UITextField!
private var imageProfile : UIImage?
private var imagePicker : EasyImagePicker?
@IBOutlet weak var collectionView: UICollectionView!
var arrImageItems = [ImageItemModel]()
@IBAction func imgtitleSaveBtn(_ sender: Any)
postServiceCall()
fileprivate func postServiceCall()
if titleTextfield.text?.trim() == ""
return self.view.makeToast("please add service title")
let parameters = ["image_title" : titleTextfield.text?.trim() ?? ""]
APIReqeustManager.sharedInstance.uploadMultipartFormData(param: parameters, url: CommonUrl.edit_profile_images, image: imageProfile, fileName: "image", vc: self, isHeaderNeeded: true) (responseData) in
print("edit profile result \(responseData)")
if let result = responseData.dict?["result"] as? NSDictionary
let success = result["status"] as? [String : Any]
let message = success?["message"] as? String
if message == "Success"
let image = result["image"] as? [String : Any]
let picId = image?["id"]
self.arrImageItems.append(ImageItemModel(title: self.titleTextfield.text, imgTitle: self.imageProfile, pic_id: picId as! Double))
self.collectionView.reloadData()
else
self.view.makeToast(CommonMessages.somethingWentWrong)
extension EditProfileImageViewController : UICollectionViewDelegate,UICollectionViewDataSource
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
return arrImageItems.count
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ImageCollectionViewCell", for: indexPath) as! ImageCollectionViewCell
cell.imgView.image = arrImageItems[indexPath.item].profileImage
cell.lblTitle.text = arrImageItems[indexPath.row].title
cell.deleteButton.tag = indexPath.row
cell.deleteButton.addTarget(self, action: #selector(deleteService(sender:)), for: UIControl.Event.touchUpInside)
return cell
使用上面的代码,我可以添加 collectionview 单元格并能够以 JSON 格式存储数据,但是.. 如果我从这个 viewcontroller 移动并返回到这个 viewcontroller,那么 collectionview 不会显示,为什么?怎么了?请帮我写代码。我卡在这里很久了。
【问题讨论】:
尝试在主线程上重新加载集合视图,看看是否能解决问题。 @KeyhanKamangar,我尝试在主线程中重新加载.. 但相同.. 这是总代码.. 我用来显示 collectionview.. 但如果我从这个 VC 移动并回来我是.没有得到collectionview ..请帮忙..我被困在这里很久了 【参考方案1】:您应该解决几个问题才能使其正常工作。我会给你每个理由。-
您正在使用具有异步网络调用的postServiceCall()
方法加载数据。无法知道控制器何时完成将数据提取到arrImageItems
数组。因此,您应该使用完成处理程序。
现在,您正在后台线程的异步 dataTask 中更新 collectionView。大错。每当您有任何与 UI 相关的任务时,您都可以在 main 线程下进行。因此,您可以按照以下方式重构代码的 APIReqeustManager.sharedInstance.uploadMultipartFormData()
部分-
APIReqeustManager.sharedInstance.uploadMultipartFormData(param: parameters, url: CommonUrl.edit_profile_images, image: imageProfile, fileName: "image", vc: self, isHeaderNeeded: true) (responseData) in
print("edit profile result \(responseData)")
if let result = responseData.dict?["result"] as? NSDictionary
let success = result["status"] as? [String : Any]
let message = success?["message"] as? String
if message == "Success"
let image = result["image"] as? [String : Any]
let picId = image?["id"]
self.arrImageItems.append(ImageItemModel(title: self.titleTextfield.text, imgTitle: self.imageProfile, pic_id: picId as! Double))
DispatchQueue.main.async
self.collectionView.reloadData()
else
DispatchQueue.main.async
self.view.makeToast(CommonMessages.somethingWentWrong)
现在,除非您希望您的视图控制器仅在触发操作 imgtitleSaveBtn(_:)
时才在您的 collectionView 中显示数据,否则您每次都需要在您的视图控制器出现在屏幕上时获取数据。要解决这个问题,您应该在viewWillAppear(_:)
方法中获取数据,例如-
override func viewWillAppear(_ animated: Bool)
super.viewWillAppear(animated)
postServiceCall()
现在,以上两个编辑应该可以解决您的问题,具体取决于您希望如何加载集合视图,但您的代码违反了相当多的编码标准。编码标准听起来像是一个派系,但相信我,如果你想在不破坏应用程序的情况下更新应用程序的功能,你会想遵循这些标准。以下只是一些提示-
-
无论何时进行异步调用,都应考虑调用完成处理程序以返回数据。
应该检查你的方法,你正在危险地破坏单一责任主体。
在不止一个地方,您强制解包。馊主意。您需要您的系统具有故障保护功能,而不仅仅是崩溃。
更新 2:
设计模式的更新:
-
以 MVC 模式划分您的代码。将
ImageItemModel
类放在它自己的文件中。请参阅下图以了解设计-
-
在 ImageCollectionViewCell 中自定义 collectionViewCell。假设您的自定义单元格只有插座。
class ImageCollectionViewCell: UICollectionViewCell
@IBOutlet weak var imgView: UIImageView!
@IBOutlet weak var lblTitle: UILabel!
@IBOutlet weak var deleteButton: UIButton!
didSet
deleteButton.addTarget(self, action: #selector(deleteService(_:)), for: .touchUpInside)
// however this could easily be done with IBAction
@objc func deleteService(_ sender: UIButton)
-
更新
postServiceCall
并使用完成处理程序将数据返回到您的控制器,这意味着当postServiceCall
执行完毕后,应根据成功或失败返回图像数组或空数组。然后控制器可以决定如何处理数据,在你的情况下更新 UI。经过几次重构,这里是更新后的控制器代码。
注意 postServiceCall 和 cellForItemAt 方法。
如果您仍然遇到同样的问题,那么您需要展示您的整个代码以获得进一步的帮助。
【讨论】:
我已根据您的回答更改了所有内容.. 但相同.. 从该 VC 转到另一个并返回后,collectionview 不会出现 这是我用来显示 collectionview 的代码。请帮助我卡在这里 由于 EasyImagePicker、ImageCollectionViewCell、APIReqeustManager 等自定义类,我无法运行您的代码。但是,collectionview 并没有消失。它显然在那里,但数据没有加载。在 numberOfItemsInSection 方法中放置一个断点,并在调试器中检查 arrImageItems.count 的值。如果 arrImageItems.count 为 0,那么您就知道数据不存在。 你在课堂上也有扩展,至少你发布的代码是这么说的。添加 ImageCollectionViewCell 和 APIReqeustManager 的代码。 还有你的 deleteService 功能。我在您的视图控制器中看不到任何 deleteService,如果 deleteService 方法不在 ViewController 中,那么您为什么采用目标操作方法而不是仅在 ImageCollectionViewCell 中创建 @IBAction以上是关于当我迅速从该视图控制器移动时,为啥我的 Collectionview 单元格没有显示?的主要内容,如果未能解决你的问题,请参考以下文章
在表格视图控制器中添加容器视图时,如何将其移动到最底部? (迅速)
当我使用自动布局移动视图时,为啥 XCode 5 没有在情节提要中添加约束