如何通过协议和委托从UITableViewCell内的UICollectionViewCell传递执行Segue Sender中的数据?


  1. 我有带有TableView的VC(a(
  2. 在UITableViewCell.xib中,我安装了一个UICollectionView
  3. UICollectionViewCell 在 UITableViewCell.xib 中注册 课程。
  4. 我想在UICollectionViewCell didSelected时执行从VC(a(到VC(b(的segue
  5. 由于 UICollectionViewCell 是在 UITableViewCell.xib 所以我不能使用 performSegue(withIdentifier: 字符串,发件人:任何(在 .xib 文件中,因为它不是 继承自UIView控制器

我在 StackOverFlow 中做了一些搜索,我找到了通过创建自定义委托人协议来执行 segue 的方法,我应用了协议,除了发送者之外,一切似乎都很好!!

我知道如何在没有协议的情况下在 VC 中使用它,但我不知道在应用协议后如何使用它

我是 Swift 语言的新手,所以请帮助我完成我的代码

下面是UITableViewCell.xib代码

protocol MyCustomCellDelegator {
func cellWasPressed()
}

class AdminPList_TableViewCell: UITableViewCell {

var delegate: MyCustomCellDelegator?

override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
setupCell()
getFProducts()
}

@IBOutlet weak var CollectionView: UICollectionView!

func getFProducts() {
productAPI.GetAllproducts { (appendThisProduct) in
self.FP_Array.append(appendThisProduct)
self.CollectionView.reloadData()
}
}

var FP_Array : [productObject] = []    
}
extension AdminPList_TableViewCell : UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {

func setupCell() {
CollectionView.delegate = self ; CollectionView.dataSource = self
CollectionView.register(UINib(nibName: "FproductsCell", bundle: nil), forCellWithReuseIdentifier: "FPcell")
//      CollectionView.register(UINib(nibName: "TproductsCell", bundle: nil), forCellWithReuseIdentifier: "TPcell")

}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

return CGSize(width: self.CollectionView.frame.size.width-10, height: self.CollectionView.frame.size.height)
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {  // make spacing between each cell
return 10
}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {

return FP_Array.count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let FPcell = CollectionView.dequeueReusableCell(withReuseIdentifier: "FPcell", for: indexPath) as! FproductsCell

FPcell.UpdateFP_cell_Content(RetrivedProducts: FP_Array[indexPath.row])

return FPcell
}


func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let selectedProduct = FP_Array[indexPath.row] // I want to pass it to sender in perform segue un ProductsLibrary Class
//      print (selectedProduct.productName)
self.delegate?.cellWasPressed()

}
}

帮助我传递选定的产品以在以下协议中执行 segue

下面是安装UITableView的VC(a(:

class ProductsLibrary : UIViewController {

override func viewDidLoad() {
super.viewDidLoad()

setupCell()
}

@IBOutlet weak var TableView: UITableView!

}

extension ProductsLibrary : UITableViewDelegate, UITableViewDataSource, MyCustomCellDelegator {

func cellWasPressed(withData:  productObject) {
performSegue(withIdentifier: "EditProduct", sender: self)

}


override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let next = segue.destination as? ProductManagement{
print ("Editing Product is Active")
let product = sender as? productObject
print(product) //it shows nil !!!
next.EditingProduct = product
}
}

func setupCell() {
TableView.delegate = self ; TableView.dataSource = self

TableView.register(UINib(nibName: "AdminPList_TableViewCell", bundle: nil), forCellReuseIdentifier: "PLcell")
}



func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

return 3
}



func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

let cell = tableView.dequeueReusableCell(withIdentifier: "PLcell", for: indexPath) as! AdminPList_TableViewCell

cell.delegate = self


return cell
}


func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {

return self.TableView.frame.size.height/3
}



}

当我开始学习委托模式时,我总是犯一些错误。所以我为自己制定了一个规则。当您必须实施委托时,请始终提醒6 个步骤

前 3 个步骤适用于将传递数据或写入协议的类,这里您的AdminPList_TableViewCell是该类。这 3 个步骤是

  1. 编写一个协议(一堆方法声明(//你做到了。
  2. 在类中声明一个将传递数据的协议变量。 你也这样做了(var delegate: MyCustomCellDelegator?(
  3. 调用你声明的方法。//你做到了(self.delegate?.cellWasPressed(((

最后 3 个步骤适用于符合该协议的类,此处产品库就是该类。

  1. 在该类中符合该协议,该协议将实现这些方法。 在这里你做到了(扩展 ProductsLibrary: ..., MyCustomCellDelegator(

  2. 将委托分配给自我,但这里的自我是什么? 好吧,self是被委派的产品库!

  3. 实现协议方法。 你做了那个:)

如何解决这个问题?

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

...
cell.delegate = self // you missed this line
...
return cell
}

现在要传递selectedProduct只需在任何地方更改协议方法定义即可。

protocol MyCustomCellDelegator {
func cellWasPressed(withData: productObject)
}

然后从didSelectItemAt方法调用

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let selectedProduct = FP_Array[indexPath.row] // I want to pass it to sender in perform segue un ProductsLibrary Class
self.delegate?.cellWasPressed(withData: selectedProduct)

}

现在在方法主体中使用它。

func cellWasPressed(withData data: productObject) {
//now use the data and write your necessary code.
performSegue(withIdentifier: "EditProduct", sender: self)
}

希望它能帮助你:)。

你好吗?

也许你的委托是零,这就是为什么你funccallWasPressed((没有调用。

实例化单元格后,您需要在 VC 上设置委托。

喜欢这个:

AdminPList_TableViewCell.delegate = self

希望对您有所帮助!

快乐编码 =D

要通过其他 VC 传递对象,您需要遵循以下 3 个步骤:

第一:在新 VC 上创建一个变量:

var selectedObject: YourKindObject?

2nd:像这样将对象传递给发件人:

func cellWasPressed(withData data: productObject) {
// pass productObject as sender
performSegue(withIdentifier: "EditProduct", sender: productObject)}

3rd:在你的覆盖方法上,你应该捕获你的 segue ID 和 passthrug 对象,如下所示:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "YourID(Can be setted on storyboard segue identifier))" {
var object = sender as! YourKindObject
let controller = segue.destination as? VC
controller?. selectedObject = object
}
}

最新更新