简体   繁体   中英

handle detail page for table view controller in swift

I have a table view controller with cells. on clicking a cell I load another view controller and I want to handle elements on this view controller. on the detail view controller I placed a label and in the first step I want to set the text of the label, but I get an exception fatal error: unexpectedly found nil while unwrapping an Optional value and I don't know why. Are there any solutions?

This is the part of my table view controller on clicking a cell:

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

    let vcMissionDetail : ViewControllerMissionDetail = self.storyboard?.instantiateViewControllerWithIdentifier("MissionDetail") as ViewControllerMissionDetail;

    //load detail view controller
    self.presentViewController(vcMissionDetail, animated: true, completion: nil)

    //set label text
    //at this line I get the exception -> label is nil
    vcMissionDetail.label.text = "Test"
}

And this is my detail view controller (very simple):

import UIKit

class ViewControllerMissionDetail: UIViewController {

    @IBOutlet var label: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

THX!

I think the solution to your problem is pretty straight forward. If I'm understanding correctly, you want to change the label on your detail view controller when you segue from table view controller using the didSelectRowAtIndexPath. The place where you are probably making a mistake is, you're trying to change the label in your detail view controller from the table view controller. The correct approach to your problem would be to set the label text in the 'viewDidLoad' or 'viewDidAppear' method of the detail view controller.

override func viewDidLoad() {
    super.viewDidLoad()
    //set label text here
}
override func viewDidAppear() {
    super.viewDidLoad()
    //OR set label text here
}

instantiateViewControllerWithIdentifier returns an optional because it may fail due to several reasons. So you should better unwrap it conditionally:

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

    if let vcMissionDetail : ViewControllerMissionDetail = self.storyboard?.instantiateViewControllerWithIdentifier("MissionDetail") as ViewControllerMissionDetail {

        //set label text before presenting the viewController
        vcMissionDetail.label.text = "Test"

        //load detail view controller
        self.presentViewController(vcMissionDetail, animated: true, completion: nil)
    }
}

Further things to double check:

Is ViewControllerMissionDetail set as the custom class for your viewController in the identity inspector in InterfaceBuilder?

If the vcMissionDetail is successfully instantiated and it still crashes then delete the label's outlet connection in InterfaceBuilder and recreate it.

For swift:

    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    self.performSegueWithIdentifier("showItemDetail", sender: tableView)
}

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
    if segue.identifier == "showItemDetail" {
        let indexPath:NSIndexPath = self.tableView.indexPathForSelectedRow()!
        let detailVC:ItemDetailViewController = segue.destinationViewController as ItemDetailViewController
        detailVC.item = items[indexPath.row] as Item

    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM