How to push a new view controller when a table cell is tapped?

你说的曾经没有我的故事 提交于 2019-12-06 04:27:36

Suppose your "locationVC" is:

class LocationVC: UIViewController {

    @IBOutlet weak var fromWhereLabel: UILabel!
    //This can be changed when creating this UIViewController
    var textToShow : String?

    override func viewWillAppear(animated: Bool) {
        if let textToShow = textToShow {
            fromWhereLabel.text = textToShow
        }
    }
}

then, just adding function below to your code in ViewController named UIViewController (that should have a better name ;-)) you can achieve your goal.

 func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
      //if such cell exists and destination controller (the one to show) exists too..
        if let subjectCell = tableView.cellForRowAtIndexPath(indexPath), let destinationViewController = navigationController?.storyboard?.instantiateViewControllerWithIdentifier("locationVC") as? LocationVC{
            //This is a bonus, I will be showing at destionation controller the same text of the cell from where it comes...
            if let text = subjectCell.textLabel?.text {
                destinationViewController.textToShow = text
            } else {
                destinationViewController.textToShow = "Tapped Cell's textLabel is empty"
            }
          //Then just push the controller into the view hierarchy
          navigationController?.pushViewController(destinationViewController, animated: true)
        }
     }

You will be able to have a LocationVC UIViewController launched every time you tap a cell, and it will have some value to prove it right. :)

Hope it Helps!

UPDATE: Code and Instructions below are for allowing to launch different UIViewControllers after tap on cells

1.- Let's create a class that will be the parent for every one of our new UIViewControllers (the ones we are willing to go from our tableview cell's tap):

public class CommonDataViewController: UIViewController {
//Here we are going to be putting any data we want to share with this view
  var data: AnyObject?
}

2.- Let's create some sort of Navigation rules, just to be organised ;-)

enum Navigation: Int {
    case vc1 = 0, vc2 = 1, vc3 = 2, vc4 = 3
    //How many rules we have (for not to exceed this number)
    static let definedNavigations = 4
    //This must return the identifier for this view on the Storyboard
    func storyboardIdentifier() -> String {
        //for this example's sake, we have a common prefix for every new view controller, if it's not the case, you can use a switch(self) here
        return "locationVC_\(self.rawValue + 1)"
    }
}

Now, let's build upon previous code:

3.- For clarity, let's change a little our previous LocationVC (that for this example, will have an Storyboard Identifier with the text "locationVC_1")

class LocationVC: CommonDataViewController {

    @IBOutlet weak var fromWhereLabel: UILabel!

    //This is optional, but improves clarity..here we take our AnyObject? variable data and transforms it into the type of data this view is excepting 
    var thisVCReceivedData: String? {
        return data as? String
    }

    override func viewWillAppear(animated: Bool) {
        if let textToShow = thisVCReceivedData {
            fromWhereLabel.text = textToShow
        }
    }
}

4.- Now, we trigger all of this in our didSelectRowAtIndexPath function.

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    //Just to avoid tapping on a cell that doesn't have an UIViewController asociated
    if Navigation.definedNavigations > indexPath.row {
        //The view's instance on our Navigation enum to which we most go after tapping this cell
        let nextView = Navigation(rawValue: indexPath.row)!
        //The identifier of the destination CommonDataViewController's son in our Storyboard
        let identifier = nextView.storyboardIdentifier()
        //If everything exists...
        if let subjectCell = tableView.cellForRowAtIndexPath(indexPath), let destinationViewController = navigationController?.storyboard?.instantiateViewControllerWithIdentifier(identifier) as? CommonDataViewController {

            //here you can use a switch around "nextView" for passing different data to every View Controller..for this example, we just pass same String to everyone
            if let text = subjectCell.textLabel?.text {
                destinationViewController.data = text
            } else {
                destinationViewController.data = "Tapped Cell's textLabel is empty"
            }
            navigationController?.pushViewController(destinationViewController, animated: true)
        }
    }
}

Notice that you can achieve same results using protocols and delegate approach, this is just simpler to explain

Well to push a view controller in a UINavigationController you just use this code:

ViewController *viewController = [self.navigationController.storyboard instantiateViewControllerWithIdentifier:@"locationVC"];
[self.navigationController pushViewController:viewController animated:YES];

The method you are looking for is this one:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    ViewController *viewController = [self.navigationController.storyboard instantiateViewControllerWithIdentifier:@"locationVC"];
    [self.navigationController pushViewController:viewController animated:YES];
}

You could use prepareForSegue method. You just need to set up the destination view. or the didselectrowatindexpath prepareForSegue code looks like :

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "nameofTheSegue"
{
    if let destinationVC = segue.destinationViewController as? OtherViewController{
        // do whatever you want with the data you want to pass.
    }
}
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!