[英]How to pass array of data between UIViewControllers from @objc function
I have a Child UICollectionViewController
where I have an array of images. 我有一个Child
UICollectionViewController
,其中有一个图像数组。 When I delete any photo I want to send back that array of updated images to Parent UIViewController
. 当我删除任何照片时,我想将更新后的图像数组发送回Parent
UIViewController
。 Also in Child controller I have a programatically view
which is called when I click on any image to expand it. 同样在Child控制器中,我有一个以编程方式
view
,当我单击任何图像以将其展开时,将调用该view
。 When the image is expanded the user can click on a Delete button to delete photos from that array. 展开图像后,用户可以单击“删除”按钮以从该阵列中删除照片。 My array is updated correctly after delete but I can't manage to send it back to parent for some reasons.
删除后,我的数组已正确更新,但是由于某些原因,我无法将其发送回父级。 I tried to send it back using Delegates and Protocols.
我尝试使用“委托和协议”将其发送回去。 Here is my code for child controller:
这是我的子控制器代码:
protocol ListImagesDelegate {
func receiveImagesUpdated(data: [String]?)
}
class ListImagesVC: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {
// Properties
var receivedImagesPath: [String]? = []
var fullscreenImageView = UIImageView()
var indexOfSelectedImage = 0
var imagesAfterDelete: [String]? = []
var delegate: ListImagesDefectDelegate?
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
print("imagesAfterDelete: \(imagesAfterDelete ?? [])") // I'm getting the right number of images in this array.
delegate?.receiveImagesUpdated(data: imagesAfterDelete)
}
...
...
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("Click on photo: \(indexPath.item + 1)")
if let imagePath = receivedImagesPath?[indexPath.item] {
guard let selectedImage = loadImageFromDiskWith(fileName: imagePath) else {return}
setupFullscreenImageView(image: selectedImage)
indexOfSelectedImage = indexPath.item
}
}
private func setupFullscreenImageView(image: UIImage){
fullscreenImageView = UIImageView(image: image)
fullscreenImageView.frame = UIScreen.main.bounds
fullscreenImageView.backgroundColor = .black
fullscreenImageView.contentMode = .scaleAspectFit
fullscreenImageView.isUserInteractionEnabled = true
self.view.addSubview(fullscreenImageView)
self.navigationController?.isNavigationBarHidden = true
self.tabBarController?.tabBar.isHidden = true
let deleteButton = UIButton(frame: CGRect(x: fullscreenImageView.bounds.maxX - 50, y: fullscreenImageView.bounds.maxY - 75, width: 30, height: 40))
deleteButton.autoresizingMask = [.flexibleLeftMargin, .flexibleBottomMargin]
deleteButton.backgroundColor = .black
deleteButton.setImage(UIImage(named: "trashIcon"), for: .normal)
deleteButton.addTarget(self, action: #selector(deleteButtonTapped), for: .touchUpInside)
fullscreenImageView.addSubview(deleteButton)
}
@objc func deleteButtonTapped(button: UIButton!) {
print("Delete button tapped")
receivedImagesPath?.remove(at: indexOfSelectedImage)
imagesAfterDelete = receivedImagesPath
collectionView.reloadData()
self.navigationController?.isNavigationBarHidden = false
self.tabBarController?.tabBar.isHidden = false
fullscreenImageView.removeFromSuperview()
}
Here is the Parent controller: 这是父控制器:
var updatedImages: [String]? = []
...
...
extension NewAlbumVC: ListImagesDelegate {
func receiveImagesUpdated(data: [String]?) {
print("New array: \(data ?? [])") // This print is never called.
updatedImages = data
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "goToImages" {
let listImagesVC = segue.destination as! ListImagesVC
listImagesVC.delegate = self
}
}
}
I want to specify that my child controller have set a Storyboard ID ( "ListImagesID"
) and also a segue identifier from parent to child ( "goToImages"
). 我想指定我的子控制器设置了一个Storyboard ID(
"ListImagesID"
),并且还设置了一个父级到子级的segue标识符( "goToImages"
)。 Can cause this any conflict ? 会引起任何冲突吗?
Thanks if you read this. 多谢您阅读。
It appears that the delegate is nil
here 看来,委托是
nil
这里
delegate?.receiveImagesUpdated(data: imagesAfterDelete)
For this 为了这
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
to trigger you must have 触发你必须有
self.performSegue(withIdentifier:"goToImages",sender:nil)
Edit: This 编辑:这
let listImagesDefectVC = storyboard?.instantiateViewController(withIdentifier: "ListImagesDefectID") as! ListImagesDefectVC
listImagesDefectVC.receivedImagesPath = imagesPath
navigationController?.pushViewController(listImagesDefectVC, animated: true)
doesn't trigger prepareForSegue
, so add 不会触发
prepareForSegue
,所以添加
listImagesDefectV.delegate = self
So finally 所以最后
Solution 1 : 解决方案1:
@objc func tapOnImageView() {
let listImagesDefectVC = storyboard?.instantiateViewController(withIdentifier: "ListImagesDefectID") as! ListImagesDefectVC
listImagesDefectVC.receivedImagesPath = imagesPath
listImagesDefectVC.delegate = self
navigationController?.pushViewController(listImagesDefectVC, animated: true)
}
Solution 2 : 解决方案2:
@objc func tapOnImageView() {
self.performSegue(withIdentifier:"goToImages",sender:nil)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "goToImages" {
let listImagesVC = segue.destination as! ListImagesVC
listImagesVC.receivedImagesPath = imagesPath
listImagesVC.delegate = self
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.