- 我有带有TableView的VC(a(
- 在UITableViewCell.xib中,我安装了一个UICollectionView
- UICollectionViewCell 在 UITableViewCell.xib 中注册 课程。
- 我想在UICollectionViewCell didSelected时执行从VC(a(到VC(b(的segue
- 由于 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 个步骤是
- 编写一个协议(一堆方法声明(//你做到了。
- 在类中声明一个将传递数据的协议变量。 你也这样做了(var delegate: MyCustomCellDelegator?(
- 调用你声明的方法。//你做到了(self.delegate?.cellWasPressed(((
最后 3 个步骤适用于符合该协议的类,此处产品库就是该类。
-
在该类中符合该协议,该协议将实现这些方法。 在这里你做到了(扩展 ProductsLibrary: ..., MyCustomCellDelegator(
-
将委托分配给自我,但这里的自我是什么? 好吧,self是被委派的产品库!
-
实现协议方法。 你做了那个:)
如何解决这个问题?
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
}
}