Sam
Sam

Reputation: 115

Prepare for segue function can't pass data to another VC Swift,

I'm trying to pass data from the alert text field to another VC's variable. And here's my alert controller.

let alert = UIAlertController(title: "Download URL", message: "", preferredStyle: .alert)
    
    let action = UIAlertAction(title: "Download", style: .default) { (action) in
        
        guard let textField = alert.textFields?.first else {return}
        
        self.ayb = textField.text ?? "Blank"
        
        UserDefaults.standard.set(self.ayb, forKey: "urlString")
        
        self.performSegue(withIdentifier: "segAdd", sender: self)
    }
    let secondAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
    
    alert.addTextField { (actionTextField) in
        actionTextField.placeholder = "Paste link here"
    }
    
    alert.addAction(action)
    alert.addAction(secondAction)
    present(alert, animated: true, completion: nil)
}

And here's my prepare function for passing data.

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "segAdd" {
        let destinationVC = tabBarController?.viewControllers?[0] as? BrowserWebViewController
        destinationVC?.urlFromDownloads = self.ayb
        print("The value of destinationVC?.urlFromDownloads is \(destinationVC?.urlFromDownloads)")
    }
}

And in the console, it writes "The value of destinationVC?.urlFromDownloads is \Optional("Text I typed in textField")".

But in BrowserWebViewController my "urlFromDownloads" is = ""(which is default).

Note: Segue's name is true.

Upvotes: 1

Views: 351

Answers (1)

vadian
vadian

Reputation: 285059

First of all rather than declaring an extra property or saving the value to UserDefaults you can pass the string in the sender parameter

let action = UIAlertAction(title: "Download", style: .default) { (action) in
    guard let textField = alert.textFields?.first else {return}
    self.performSegue(withIdentifier: "segAdd", sender: textField.text!)
}

Your way to determine the destination view controller is wrong. Ask the segue for the destination. And you can force downcast the type. The code must not crash if the segue is designed correctly.

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "segAdd" {
        let destinationVC = segue.destination as! BrowserWebViewController
        destinationVC.urlFromDownloads = sender as! String
        print("The value of destinationVC?.urlFromDownloads is \(destinationVC.urlFromDownloads)")
    }
}

Upvotes: 1

Related Questions