使用委托和协议的集合视图单元格操作
Posted
技术标签:
【中文标题】使用委托和协议的集合视图单元格操作【英文标题】:Collection View Cell Action using Delegates and Protocols 【发布时间】:2019-08-23 13:24:41 【问题描述】:我创建了一个包含 UITableView 的 View Controller,每个 UITableViewCell 都包含一个 UICollectionView。
我进行了 2 次 API 调用,每个 collectionView 都会显示每个 API 调用的前 5 个结果。
另外,我在每个 TableView 标题的右上角添加了一个按钮,标题为“全部显示”。您可以在下图中看到屏幕。
这是我添加 tableView 标题按钮的方法:
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?
let headerView = UIView(frame: CGRect(x: 0, y: 0, width: tableView.frame.width, height: 100))
let showHideButton: UIButton = UIButton(frame: CGRect(x:headerView.frame.size.width - 80, y:0, width:75, height:35))
showHideButton.setTitle("Show All", for: .normal)
showHideButton.titleLabel?.font = UIFont.boldSystemFont(ofSize: 18)
showHideButton.setTitleColor(#colorLiteral(red: 0.9607843137, green: 0.007843137255, blue: 0.03137254902, alpha: 1), for: .normal)
//showHideButton.addTarget(self, action: #selector(btnShowHideTapped), for: .touchUpInside)
headerView.addSubview(showHideButton)
return headerView
当我点击 tableView 标题上的“显示全部”按钮时,我想跳转到另一个视图控制器(“showAllViewController”)并表示我的对象的所有结果,当我点击 CollectionViewCell 的图像时,我想跳转到另一个视图控制器(“detailsViewController”)。我如何使用委托和协议来做到这一点?
这是我的屏幕的示例图像:
编辑:我按照这个问题 (navigate on click of collectionview cell inside tableview) 中的以下步骤操作,但我不知道我需要在“cellTapped()”函数上写什么:
ViewController.swift :
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! CategoryRow
cell.delegate = self
return cell
MyCell.swift :
protocol CategoryRowDelegate:class
func cellTapped()
CategoryRow.swift :
class CategoryRow : UITableViewCell
weak var delegate:CategoryRowDelegate?
@IBOutlet weak var collectionView: UICollectionView!
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
if delegate!= nil
delegate?.cellTapped()
在 ViewController 中添加委托函数
func cellTapped()
//code for navigation
//I don't know what to write
谁能帮帮我?
【问题讨论】:
我认为您不需要委托来执行此操作,您可以直接在单元格点击或按钮操作事件上显示视图控制器 使用 //showHideButton.addTarget(self, action:#selector(btnShowHideTapped),for: .touchUpInside)。然后在 btnShowHideTapped() 中使用 segue(或许多方法中的另一种)转到下一个视图控制器。然后在 prepareForSegue 中,您可以根据需要将一些信息发送到下一个视图控制器。 这行代码是从网上复制粘贴的。我需要在选择器属性中添加什么? 您将处理水龙头的函数的名称放在选择器部分。下面是一个例子:addTarget(self, action: #selector(NameOfFunctionWhichHandles), for: UIControl.Event.touchUpInside) 什么应该包含处理水龙头的功能? 【参考方案1】:首先我会建议你在创建按钮时插入一个标签,这样你就知道用户点击了集合中的哪个按钮,然后添加:
showHideButton.tag = section // assign the section number to the tag of the button
然后,正如您已经在代码中编写的那样,您为按钮单击分配一个动作:
showHideButton.addTarget(self, action: #selector(self.btnShowHideTapped(sender:)), for: .touchUpInside)
所以你最终会得到类似的东西:
showHideButton.setTitle("Show All", for: .normal)
showHideButton.titleLabel?.font = UIFont.boldSystemFont(ofSize: 18)
showHideButton.setTitleColor(#colorLiteral(red: 0.9607843137, green: 0.007843137255, blue: 0.03137254902, alpha: 1), for: .normal)
showHideButton.tag = section // section Number for Header
showHideButton.addTarget(self, action: #selector(self.btnShowHideTapped(sender:)), for: .touchUpInside) // Sender UIButton
在你的函数中你回调点击=>
@objc func btnShowHideTapped(sender: UIButton)
print(sender.tag)
// Switch Action if is HeaderView 0 or HeaderView 1 etc...
// self.present(YourViewController...) OR self.performSegue(withIdentifier: "detailsViewController", sender: nil)
我希望我一直在你身边。告诉我。
【讨论】:
谢谢!但我想用当前的集合视图数据呈现一个视图控制器。每次都不是同一个静态视图控制器。我想通过某种方式我需要覆盖准备函数。对吗? 你能告诉我当我点击单元格时如何跳转到另一个视图控制器吗?这对我现在更重要。谢谢! 我回答了你,只是制作或礼物或调用追随者......取决于你想如何移动到下一个视图控制器......看看我写给你的例子......跨度> 你也可以看这里:***.com/questions/24099533/… 或 developer.apple.com/documentation/uikit/uiviewcontroller/… 这一切都取决于你想如何呈现你的 viewController 好的,谢谢!这适用于“显示全部”按钮。当我点击 collectionView 单元格时会怎样?【参考方案2】:1] In separate dataSource method - create protocol
protocol myProductsDelegate: class
func cellTaped()
class ProductsDataSource: NSObject, UICollectionViewDataSource
var delegate: myProductsDelegate?
// func collectionView(_ collectionView: UICollectionView, //numberOfItemsInSection section: Int) -> Int
//
// return
//
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! ProductsCollectionViewCell
return cell
2] In separate delegate method -
class ProductsDelegate: NSObject, UICollectionViewDelegate
var delegate: myProductsDelegate?
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
if delegate != nil
delegate?.cellTaped()
3] Note: In viewDidload -
self.CollectionView.delegate = self.myDelegate
self.CollectionView.dataSource = self.myDataSource
self.myDelegate.delegate = self
4] In your main view controller where collectionView is available -
var myDelegate: ProductsDelegate = ProductsDelegate()
var myDataSource: ProductsDataSource = ProductsDataSource()
extension MainViewController: ProductsDelegate
func cellTaped()
let vc = storyboard?.instantiateViewController(identifier: "SecondViewController") as? SecondViewController
self.present(vc!, animated: true, completion: nil)
【讨论】:
以上是关于使用委托和协议的集合视图单元格操作的主要内容,如果未能解决你的问题,请参考以下文章
在实例化单元格之前调用 UICollectionView 委托方法?