I have a collection view inside a table view and a button in the collection view cell. I want to push another vc when that button is pressed.
I tried creating a delegate in the collection view cell, but the collection view cell has a cellforitem method in the table cell, so the delegate cannot be declared in the main view controller.
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .black
setUpTableView()
}
func setUpTableView() {
let tableView = UITableView()
view.addSubview(tableView)
tableView.register(
HomeRecommendStoreTableViewCell.self,
forCellReuseIdentifier: HomeRecommendStoreTableViewCell.identifier
)
tableView.register(
UITableViewCell.self,
forCellReuseIdentifier: "cell"
)
tableView.delegate = self
tableView.dataSource = self
tableView.backgroundColor = .black
tableView.showsVerticalScrollIndicator = false
tableView.separatorStyle = .none
tableView.contentInsetAdjustmentBehavior = .never
self.tableView = tableView
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: HomePopularTableViewCell.identifier, for: indexPath) as? HomePopularTableViewCell else { return tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)}
cell.selectionStyle = .none
return cell
}
}
class TableViewCell: UITableViewCell, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
static let identifier = "HomeRecommendStoreTableViewCell"
private var collectionView: UICollectionView!
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
contentView.backgroundColor = .black
setUpCollectionView()
}
required init?(coder: NSCoder) {
fatalError()
}
func setUpCollectionView() {
let layout = UICollectionViewFlowLayout()
let collectionView = UICollectionView(
frame: .zero,
collectionViewLayout: layout
)
layout.scrollDirection = .horizontal
collectionView.register(
HomeRecommendStoreCollectionViewCell.self,
forCellWithReuseIdentifier: HomeRecommendStoreCollectionViewCell.identifier
)
collectionView.register(
UICollectionViewCell.self,
forCellWithReuseIdentifier: "cell"
)
collectionView.clipsToBounds = false
collectionView.backgroundColor = .black
collectionView.showsHorizontalScrollIndicator = false
collectionView.delegate = self
collectionView.dataSource = self
contentView.addSubview(collectionView)
collectionView.snp.makeConstraints { make in
make.top.equalToSuperview().offset(40)
make.leading.equalToSuperview().offset(20)
make.trailing.equalToSuperview()
make.bottom.equalToSuperview().inset(80)
}
self.collectionView = collectionView
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 5
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(
withReuseIdentifier: HomeRecommendStoreCollectionViewCell.identifier, for: indexPath
) as? HomeRecommendStoreCollectionViewCell else {
return collectionView.dequeueReusableCell(
withReuseIdentifier: "cell", for: indexPath
)
}
return cell
}
}
class CollectionViewCell: UICollectionViewCell {
static let identifier = "HomeRecommendStoreCollectionViewCell"
private lazy var listButton: UIButton = {
let button = UIButton()
return button
}()
override init(frame: CGRect) {
super.init(frame: frame)
setUp()
}
func setUp() {
listButton.addTarget(self, action: #selector(onTap), for: .touchUpInside)
}
@objc func onTap() {
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
CodePudding user response:
First you have to make a property in tableViewCell:
weak var parent:ViewController?
Then in viewController you have to use cell for row of tableView:
cell.parent = self
Then create same property in collectionViewCell:
weak var parent:ViewController?
And use collectionView func cell for item at:
cell.parent = parent
And use that parent inside your button func:
@objc func onTap() {
let destinationVC = NextViewController()
parent?.navigationController.pushViewController(destinationVC,animated:true)
}
CodePudding user response:
Since the delegate is inside the collectionView, you can get a callback in TableView cell and then with another delegate you can get the call back in your ViewController.
Or else you can also use notifications in order to get callbacks.
Or closures can also be used.