Home > database >  How to push view controller on a button tap in nested collection view cell swift
How to push view controller on a button tap in nested collection view cell swift

Time:10-27

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.

  • Related