Switch View Controller From TableViewCell Class in Swift











up vote
3
down vote

favorite












I would like to present a new ViewController when user clicks element in tableviewcell. The standard code for launching a VC, however, does not work from a tableview cell or even in a helper class because neither a TVC nor a helper class can present a view controller.



Here is the code in a helper class. Whether placed in the helperclass or the tableview cell, it doesn't have a present method to launch a VC.



class launchVC {
func launchVCNamed(identifier: String) {
let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let secondVC = storyBoard.instantiateViewController(withIdentifier: "contactDetail")
//FOLLOWING LINE HAS ERROR NO SUCH MEMBER (present)
self.present(secondVC, animated: true, completion: nil)
}
}


How can I modify this to launch a VC?










share|improve this question


























    up vote
    3
    down vote

    favorite












    I would like to present a new ViewController when user clicks element in tableviewcell. The standard code for launching a VC, however, does not work from a tableview cell or even in a helper class because neither a TVC nor a helper class can present a view controller.



    Here is the code in a helper class. Whether placed in the helperclass or the tableview cell, it doesn't have a present method to launch a VC.



    class launchVC {
    func launchVCNamed(identifier: String) {
    let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
    let secondVC = storyBoard.instantiateViewController(withIdentifier: "contactDetail")
    //FOLLOWING LINE HAS ERROR NO SUCH MEMBER (present)
    self.present(secondVC, animated: true, completion: nil)
    }
    }


    How can I modify this to launch a VC?










    share|improve this question
























      up vote
      3
      down vote

      favorite









      up vote
      3
      down vote

      favorite











      I would like to present a new ViewController when user clicks element in tableviewcell. The standard code for launching a VC, however, does not work from a tableview cell or even in a helper class because neither a TVC nor a helper class can present a view controller.



      Here is the code in a helper class. Whether placed in the helperclass or the tableview cell, it doesn't have a present method to launch a VC.



      class launchVC {
      func launchVCNamed(identifier: String) {
      let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
      let secondVC = storyBoard.instantiateViewController(withIdentifier: "contactDetail")
      //FOLLOWING LINE HAS ERROR NO SUCH MEMBER (present)
      self.present(secondVC, animated: true, completion: nil)
      }
      }


      How can I modify this to launch a VC?










      share|improve this question













      I would like to present a new ViewController when user clicks element in tableviewcell. The standard code for launching a VC, however, does not work from a tableview cell or even in a helper class because neither a TVC nor a helper class can present a view controller.



      Here is the code in a helper class. Whether placed in the helperclass or the tableview cell, it doesn't have a present method to launch a VC.



      class launchVC {
      func launchVCNamed(identifier: String) {
      let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
      let secondVC = storyBoard.instantiateViewController(withIdentifier: "contactDetail")
      //FOLLOWING LINE HAS ERROR NO SUCH MEMBER (present)
      self.present(secondVC, animated: true, completion: nil)
      }
      }


      How can I modify this to launch a VC?







      ios swift presentviewcontroller






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 19 at 1:06









      user1904273

      1,52082761




      1,52082761
























          2 Answers
          2






          active

          oldest

          votes

















          up vote
          3
          down vote



          accepted










          Generally you should use delegate pattern, or closure to pass a block from cell back to view controller. I prefer using closures to delegates so I'll give such example:



          class SomeCell: UITableViewCell {
          var actionBlock = { }

          func someActionOccured() { // some action like button tap in cell occured
          actionBlock()
          }
          }


          And in cellForRow in view controller you need to assign the closure



          func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
          let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! SomeCell // replace cell identifier with whatever your identifier is
          cell.actionBlock = { [unowned self] in
          let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
          let secondVC = storyBoard.instantiateViewController(withIdentifier: "contactDetail")
          self.present(secondVC, animated: true, completion: nil)
          }
          return cell
          }





          share|improve this answer




























            up vote
            1
            down vote













            Add a delegate to your cell and assign it to the presentingVC. See below.



            Using Delegation



            Create a CustomCell that inherits from UITableViewCell.



            class CustomCell: UITableViewCell {
            var cellDelegate : CustomCellDelegate = nil

            @IBAction func elementTapped() {
            cellDelegate?.launchVC()
            }
            }


            Custom Cell Delegate



            protocol CustomCellDelegate {
            func launchVC()
            }


            MainViewController



            class ViewController: UIViewController, UITableViewControllerDataSource, UITableViewDelegate {

            IBOutlet weak var tableView: UITableView!

            override func viewDidLoad() {
            tableView.dataSource = self
            tableView.delegate = self
            }

            func numberOfSections(in: UITableView) -> Int {
            return 1
            }

            func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return 1
            }

            func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            if let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as? CustomCell {

            // important
            cell.delegate = self
            return cell
            }
            }
            }


            Extend ViewController to implement the protocol



            extension ViewContrller: CustomCellDelegate {
            func launchVC() {
            let storyboard = UIStoryboard.init(name: "Main", bundle: nil)
            let vc = storyboard.instantiateViewController(withIdentifier: "SecondViewController")
            self.present(vc, animated: true, completion: nil)
            }
            }





            share|improve this answer























            • Apologies, if you're trying to present a VC from a TableViewCell, @olejnjak has the correct implementation.
              – Richard Poutier
              Nov 19 at 1:42











            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














             

            draft saved


            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53367091%2fswitch-view-controller-from-tableviewcell-class-in-swift%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            2 Answers
            2






            active

            oldest

            votes








            2 Answers
            2






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            3
            down vote



            accepted










            Generally you should use delegate pattern, or closure to pass a block from cell back to view controller. I prefer using closures to delegates so I'll give such example:



            class SomeCell: UITableViewCell {
            var actionBlock = { }

            func someActionOccured() { // some action like button tap in cell occured
            actionBlock()
            }
            }


            And in cellForRow in view controller you need to assign the closure



            func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! SomeCell // replace cell identifier with whatever your identifier is
            cell.actionBlock = { [unowned self] in
            let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
            let secondVC = storyBoard.instantiateViewController(withIdentifier: "contactDetail")
            self.present(secondVC, animated: true, completion: nil)
            }
            return cell
            }





            share|improve this answer

























              up vote
              3
              down vote



              accepted










              Generally you should use delegate pattern, or closure to pass a block from cell back to view controller. I prefer using closures to delegates so I'll give such example:



              class SomeCell: UITableViewCell {
              var actionBlock = { }

              func someActionOccured() { // some action like button tap in cell occured
              actionBlock()
              }
              }


              And in cellForRow in view controller you need to assign the closure



              func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
              let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! SomeCell // replace cell identifier with whatever your identifier is
              cell.actionBlock = { [unowned self] in
              let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
              let secondVC = storyBoard.instantiateViewController(withIdentifier: "contactDetail")
              self.present(secondVC, animated: true, completion: nil)
              }
              return cell
              }





              share|improve this answer























                up vote
                3
                down vote



                accepted







                up vote
                3
                down vote



                accepted






                Generally you should use delegate pattern, or closure to pass a block from cell back to view controller. I prefer using closures to delegates so I'll give such example:



                class SomeCell: UITableViewCell {
                var actionBlock = { }

                func someActionOccured() { // some action like button tap in cell occured
                actionBlock()
                }
                }


                And in cellForRow in view controller you need to assign the closure



                func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
                let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! SomeCell // replace cell identifier with whatever your identifier is
                cell.actionBlock = { [unowned self] in
                let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
                let secondVC = storyBoard.instantiateViewController(withIdentifier: "contactDetail")
                self.present(secondVC, animated: true, completion: nil)
                }
                return cell
                }





                share|improve this answer












                Generally you should use delegate pattern, or closure to pass a block from cell back to view controller. I prefer using closures to delegates so I'll give such example:



                class SomeCell: UITableViewCell {
                var actionBlock = { }

                func someActionOccured() { // some action like button tap in cell occured
                actionBlock()
                }
                }


                And in cellForRow in view controller you need to assign the closure



                func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
                let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! SomeCell // replace cell identifier with whatever your identifier is
                cell.actionBlock = { [unowned self] in
                let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
                let secondVC = storyBoard.instantiateViewController(withIdentifier: "contactDetail")
                self.present(secondVC, animated: true, completion: nil)
                }
                return cell
                }






                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 19 at 1:14









                olejnjak

                368212




                368212
























                    up vote
                    1
                    down vote













                    Add a delegate to your cell and assign it to the presentingVC. See below.



                    Using Delegation



                    Create a CustomCell that inherits from UITableViewCell.



                    class CustomCell: UITableViewCell {
                    var cellDelegate : CustomCellDelegate = nil

                    @IBAction func elementTapped() {
                    cellDelegate?.launchVC()
                    }
                    }


                    Custom Cell Delegate



                    protocol CustomCellDelegate {
                    func launchVC()
                    }


                    MainViewController



                    class ViewController: UIViewController, UITableViewControllerDataSource, UITableViewDelegate {

                    IBOutlet weak var tableView: UITableView!

                    override func viewDidLoad() {
                    tableView.dataSource = self
                    tableView.delegate = self
                    }

                    func numberOfSections(in: UITableView) -> Int {
                    return 1
                    }

                    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
                    return 1
                    }

                    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
                    if let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as? CustomCell {

                    // important
                    cell.delegate = self
                    return cell
                    }
                    }
                    }


                    Extend ViewController to implement the protocol



                    extension ViewContrller: CustomCellDelegate {
                    func launchVC() {
                    let storyboard = UIStoryboard.init(name: "Main", bundle: nil)
                    let vc = storyboard.instantiateViewController(withIdentifier: "SecondViewController")
                    self.present(vc, animated: true, completion: nil)
                    }
                    }





                    share|improve this answer























                    • Apologies, if you're trying to present a VC from a TableViewCell, @olejnjak has the correct implementation.
                      – Richard Poutier
                      Nov 19 at 1:42















                    up vote
                    1
                    down vote













                    Add a delegate to your cell and assign it to the presentingVC. See below.



                    Using Delegation



                    Create a CustomCell that inherits from UITableViewCell.



                    class CustomCell: UITableViewCell {
                    var cellDelegate : CustomCellDelegate = nil

                    @IBAction func elementTapped() {
                    cellDelegate?.launchVC()
                    }
                    }


                    Custom Cell Delegate



                    protocol CustomCellDelegate {
                    func launchVC()
                    }


                    MainViewController



                    class ViewController: UIViewController, UITableViewControllerDataSource, UITableViewDelegate {

                    IBOutlet weak var tableView: UITableView!

                    override func viewDidLoad() {
                    tableView.dataSource = self
                    tableView.delegate = self
                    }

                    func numberOfSections(in: UITableView) -> Int {
                    return 1
                    }

                    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
                    return 1
                    }

                    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
                    if let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as? CustomCell {

                    // important
                    cell.delegate = self
                    return cell
                    }
                    }
                    }


                    Extend ViewController to implement the protocol



                    extension ViewContrller: CustomCellDelegate {
                    func launchVC() {
                    let storyboard = UIStoryboard.init(name: "Main", bundle: nil)
                    let vc = storyboard.instantiateViewController(withIdentifier: "SecondViewController")
                    self.present(vc, animated: true, completion: nil)
                    }
                    }





                    share|improve this answer























                    • Apologies, if you're trying to present a VC from a TableViewCell, @olejnjak has the correct implementation.
                      – Richard Poutier
                      Nov 19 at 1:42













                    up vote
                    1
                    down vote










                    up vote
                    1
                    down vote









                    Add a delegate to your cell and assign it to the presentingVC. See below.



                    Using Delegation



                    Create a CustomCell that inherits from UITableViewCell.



                    class CustomCell: UITableViewCell {
                    var cellDelegate : CustomCellDelegate = nil

                    @IBAction func elementTapped() {
                    cellDelegate?.launchVC()
                    }
                    }


                    Custom Cell Delegate



                    protocol CustomCellDelegate {
                    func launchVC()
                    }


                    MainViewController



                    class ViewController: UIViewController, UITableViewControllerDataSource, UITableViewDelegate {

                    IBOutlet weak var tableView: UITableView!

                    override func viewDidLoad() {
                    tableView.dataSource = self
                    tableView.delegate = self
                    }

                    func numberOfSections(in: UITableView) -> Int {
                    return 1
                    }

                    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
                    return 1
                    }

                    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
                    if let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as? CustomCell {

                    // important
                    cell.delegate = self
                    return cell
                    }
                    }
                    }


                    Extend ViewController to implement the protocol



                    extension ViewContrller: CustomCellDelegate {
                    func launchVC() {
                    let storyboard = UIStoryboard.init(name: "Main", bundle: nil)
                    let vc = storyboard.instantiateViewController(withIdentifier: "SecondViewController")
                    self.present(vc, animated: true, completion: nil)
                    }
                    }





                    share|improve this answer














                    Add a delegate to your cell and assign it to the presentingVC. See below.



                    Using Delegation



                    Create a CustomCell that inherits from UITableViewCell.



                    class CustomCell: UITableViewCell {
                    var cellDelegate : CustomCellDelegate = nil

                    @IBAction func elementTapped() {
                    cellDelegate?.launchVC()
                    }
                    }


                    Custom Cell Delegate



                    protocol CustomCellDelegate {
                    func launchVC()
                    }


                    MainViewController



                    class ViewController: UIViewController, UITableViewControllerDataSource, UITableViewDelegate {

                    IBOutlet weak var tableView: UITableView!

                    override func viewDidLoad() {
                    tableView.dataSource = self
                    tableView.delegate = self
                    }

                    func numberOfSections(in: UITableView) -> Int {
                    return 1
                    }

                    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
                    return 1
                    }

                    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
                    if let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as? CustomCell {

                    // important
                    cell.delegate = self
                    return cell
                    }
                    }
                    }


                    Extend ViewController to implement the protocol



                    extension ViewContrller: CustomCellDelegate {
                    func launchVC() {
                    let storyboard = UIStoryboard.init(name: "Main", bundle: nil)
                    let vc = storyboard.instantiateViewController(withIdentifier: "SecondViewController")
                    self.present(vc, animated: true, completion: nil)
                    }
                    }






                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited Nov 19 at 1:59

























                    answered Nov 19 at 1:40









                    Richard Poutier

                    439




                    439












                    • Apologies, if you're trying to present a VC from a TableViewCell, @olejnjak has the correct implementation.
                      – Richard Poutier
                      Nov 19 at 1:42


















                    • Apologies, if you're trying to present a VC from a TableViewCell, @olejnjak has the correct implementation.
                      – Richard Poutier
                      Nov 19 at 1:42
















                    Apologies, if you're trying to present a VC from a TableViewCell, @olejnjak has the correct implementation.
                    – Richard Poutier
                    Nov 19 at 1:42




                    Apologies, if you're trying to present a VC from a TableViewCell, @olejnjak has the correct implementation.
                    – Richard Poutier
                    Nov 19 at 1:42


















                     

                    draft saved


                    draft discarded



















































                     


                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53367091%2fswitch-view-controller-from-tableviewcell-class-in-swift%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Create new schema in PostgreSQL using DBeaver

                    Deepest pit of an array with Javascript: test on Codility

                    Costa Masnaga