1
votes

I have tableView, in which there are imageView and label, when i select cell I want to push another viewController and show in it my selected cell imageView.image and label.text, but there is error that (Unexpectedly found nil while implicitly unwrapping an Optional value) in image line

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let vc = storyboard?.instantiateViewController(withIdentifier: "PushedViewController") as? PushedViewController
    vc?.pushedImage.image = UIImage(named: imagesArray[indexPath.row])
    vc?.pushedLabel.text = imagesArray[indexPath.row]
    self.navigationController?.pushViewController(vc!, animated: true)
}

Unexpectedly found nil while implicitly unwrapping an Optional value

3
On which line do you get an error?levan

3 Answers

0
votes

you've posted not too much, but it seems the crashing line is

self.navigationController?.pushViewController(vc!, animated: true)

are you sure this storyboard?.instantiateViewController(withIdentifier: "PushedViewController") as? PushedViewController is not nil?

maybe PushedViewController is not in the same storyboard. Anyway just put it in a guard let to unwrap the optional

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    guard let vc = storyboard?.instantiateViewController(withIdentifier: "PushedViewController") as? PushedViewController else { //fallback goes here return }
    vc.pushedImage.image = UIImage(named: imagesArray[indexPath.row])
    vc.pushedLabel.text = imagesArray[indexPath.row]
    self.navigationController?.pushViewController(vc, animated: true)
}
0
votes

In your first view controller selectedImage and selectedText will be nil in tableView didSelectRowAt method. The IBOutlets will be initiated only after you've pushed the second view controller. So create a UIImage and String variables in the second view controller and send values to these variables. In the second view controller's viewDidLoad method assign the passed values to the IBOutlets.

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let vc = storyboard?.instantiateViewController(withIdentifier: "PushedViewController") as? PushedViewController
    //vc?.pushedImage vc?.pushedLabel are nil
    vc?.selectedImage = UIImage(named: imagesArray[indexPath.row])
    vc?.selectedText = imagesArray[indexPath.row]
    self.navigationController?.pushViewController(vc!, animated: true)
}

PushedViewController

class PushedViewController: UIViewController {
    @IBOutlet weak var pushedLabel: UILabel!
    @IBOutlet weak var pushedImage: UIImageView!
    var selectedImage: UIImage?
    var selectedText: String?
    override func viewDidLoad() {
        super.viewDidLoad()
        //vc?.pushedImage vc?.pushedLabel are not nil
        pushedImage.image = selectedImage
        pushedLabel.text = selectedText
    }
}
0
votes

The UI components is not yet initialised, so you can not access them right after you initialise the controller.

I'd suggest you to have a local variable in the PushedViewController to store image and text and then assign those in viewDidLoad.

Like this:

class PushedViewController: UIViewController {
    //..
    var image:UIImage?
    var text:String?
    //..
    override viewDidLoad() {
        super.viewDidLoad()
        //..
        if let image = self.image {
            self.imageView.image = image
        }
        if let text = self.text {
            self.label.text = text
        }
        //..
    }
    //..
}

Then set those properties from where you are pushing the controller:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    guard let vc = storyboard?.instantiateViewController(withIdentifier: "PushedViewController") as? PushedViewController else { return }
    // Assign the properties here
    vc.image = UIImage(named: imagesArray[indexPath.row])
    vc.text = textsArray[indexPath.row]
    self.navigationController?.pushViewController(vc, animated: true)
}