ios - 如何从@objc函数在UIViewControllers之间传递数据数组
问题描述
我有一个孩子UICollectionViewController
,我有一系列图像。当我删除任何照片时,我想将该更新图像数组发送回 Parent UIViewController
。同样在子控制器中,我有一个编程view
方式,当我单击任何图像以展开它时会调用它。当图像展开时,用户可以单击删除按钮从该阵列中删除照片。删除后我的数组已正确更新,但由于某些原因我无法将其发送回父级。我尝试使用代表和协议将其发回。这是我的子控制器代码:
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()
}
这是父控制器:
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
}
}
}
我想指定我的子控制器设置了 Storyboard ID ( "ListImagesID"
) 以及从父级到子级 ( "goToImages"
) 的 segue 标识符。会导致这任何冲突吗?
谢谢你读到这个。
解决方案
看来委托人来nil
了
delegate?.receiveImagesUpdated(data: imagesAfterDelete)
为了这
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
要触发你必须有
self.performSegue(withIdentifier:"goToImages",sender:nil)
编辑:这个
let listImagesDefectVC = storyboard?.instantiateViewController(withIdentifier: "ListImagesDefectID") as! ListImagesDefectVC
listImagesDefectVC.receivedImagesPath = imagesPath
navigationController?.pushViewController(listImagesDefectVC, animated: true)
不会触发prepareForSegue
,所以添加
listImagesDefectV.delegate = self
所以最后
解决方案 1:
@objc func tapOnImageView() {
let listImagesDefectVC = storyboard?.instantiateViewController(withIdentifier: "ListImagesDefectID") as! ListImagesDefectVC
listImagesDefectVC.receivedImagesPath = imagesPath
listImagesDefectVC.delegate = self
navigationController?.pushViewController(listImagesDefectVC, animated: true)
}
解决方案 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
}
}
推荐阅读
- python - 如何在 Django 中使用 for 循环将每个文件保存在 request.FILES 中?
- preg-match-all - 如何使用 Preg_match_all 从多个数据中获取单个值
- php - PHP字符串不连接
- javascript - 我应该如何使用节点在猫鼬的“组”模型中将新用户添加到用户列表中?
- javascript - 在onclick函数中获取Class的变量
- html - 如何将 FileReader 结果加载到 HTML5 视频中以实现跨浏览器和设备的最佳兼容性
- python - 带有 if 语句的 lambda 函数的语法无效
- c# - 为列表中的每个项目设置权重
- haskell - Haskell - 你如何制作一个包含 getLine 的循环?
- python - 如何使用一个主键将不同的 CSV 文件合并为一个新的 CSV