I did some searches in StackOverFlow and I found methods to perform segue by creating a custom delegator protocol I applied the protocol and everything seems OK except the sender!!
I know how to use it inside VC without protocol but I don't know how to use it after applying the protocol
I'm new to Swift Language and so please help me to complete my code
Here below is the UITableViewCell.xib code
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()
}
}
Help me to pass selectedProduct to perform segue in below protocol
And here below is the VC(a) where the UITableView is installed:
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
}
}
When I started learning the delegation pattern I always made some mistakes. So I make a rule for myself. When you have to implement a delegate always remind 6 steps.
The First 3 steps are for the class that will pass the data or write protocol, here your AdminPList_TableViewCell is that class. The 3 steps are
The Last 3 steps are for the class that will conform that protocol, here ProductsLibrary is that class.
Conform that protocol in that class which will implement those methods. // here you did that (extension ProductsLibrary: ..., MyCustomCellDelegator)
Assign delegate to self, but what is self here? well, self is the ProductsLibrary which has been delegated! // you missed that
Implement the protocol methods. // you did that :)
How to solve this?
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
...
cell.delegate = self // you missed this line
...
return cell
}
Now for passing selectedProduct just change the protocol method definition everywhere.
protocol MyCustomCellDelegator {
func cellWasPressed(withData: productObject)
}
Then call from the didSelectItemAt
method
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)
}
Now use it inside the method body.
func cellWasPressed(withData data: productObject) {
//now use the data and write your necessary code.
performSegue(withIdentifier: "EditProduct", sender: self)
}
Hope it will help you :).