Search code examples
iosiphoneswiftuicollectionviewpresentviewcontroller

How to present a ViewController after pressing a button inside of a CollectionViewCell


Hey i'm new to programming and my problem is, i have a UICollectionViewController with 4 cells that are horizontal scrollable. Inside of the 4th cell i have a UIButton(optionsButton) on top of a UIView (ProfileContainerView).

The UIViewController I want to present is called ProfileEditViewController and is set up in Main.storyboard.

How can i present a UIViewController after pressing this button?

ProfileCell:

class ProfileCell: UICollectionViewCell {

    let profileContainerView: UIView = {
        let view = UIView()
        return view
    }()

    lazy var optionsButton: UIButton = {
        let btn = UIButton(type: .custom)
        btn.setImage(#imageLiteral(resourceName: "Settings"), for: UIControlState.normal)
        btn.addTarget(self, action: #selector(handleOptionsButton), for: UIControlEvents.touchUpInside)
        return btn
    }()

    @objc func handleOptionsButton() {
        print("Button pressed")
    }
}

HomeViewController:

class HomeViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout {


    let profileCelId = "profileCell"

    override func viewDidLoad() {
        super.viewDidLoad()
        setupSwipeView()
    }


    func setupSwipeView() {
        collectionView?.register(UICollectionViewCell.self, forCellWithReuseIdentifier: cell)
        collectionView?.register(ProfileCell.self, forCellWithReuseIdentifier: profileCelId)        
    }


    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {        
        if indexPath.item == 3 {
            return collectionView.dequeueReusableCell(withReuseIdentifier: profileCelId, for: indexPath)
        }
        return cell
    }
}

Solution

  • You can present your ProfileEditViewController, which is styled in your Main.storyboard the following way:

    1) Give your ProfileEditViewController a StoryBoard ID. E.g. "ProfileEditViewController" - Some question regarding this is here: What is a StoryBoard ID and how can i use this?

    2) Register the UIViewController for the action on the UIButton or offer an appropriate callback functionality. As your HomeViewController is also your Collection View's datasource, you can easily extend your DataSource method

    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell`
    

    Implementation could look like:

    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {        
        if indexPath.item == 3 {
            let profileCell = collectionView.dequeueReusableCell(withReuseIdentifier: profileCelId, for: indexPath)
            if let _cell = cell as? ProfileCell,
               let button = _cell.optionsButton as? UIButton {
                button.addTarget(self, action: #selector(handleOptionsButton), forControlEvents: UIControlEvents.TouchUpInside)
            }
            return profileCell;
        }
        return cell
    }
    

    Make sure that your buttons Action is now also being implemented by your HomeViewController

    @objc func handleOptionsButton() {
        print("Button pressed")
    }
    

    3) Now in HomeViewController.handleOptionsButton you need to provide a functionality to support the transition to that specific Controller with the desired StoryboardID:

    let storyboard = UIStoryboard(name: "Main", bundle:Bundle.main)
    let controller = storyboard.instantiateViewController(withIdentifier: "ProfileEditViewController")
    self.present(controller, animated: true, completion: nil)