Hello i am facing the problem as the prepare for segue function is not working properly i've the code can you please tell me how can i debug it as it has optional conditions how i can remove them and check what's the problem or what i am doing wrong as i just want a class to be initialized in target vc before the app navigates to other screen.
#IBAction func filterBtnPressed(_ sender: Any) {
self.performSegue(withIdentifier: "FilterSessionVC", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "FilterSessionVC", let navigation = segue.destination as? UINavigationController, let vc = navigation.topViewController as? FilterSessionVC {
vc.presenter = FilterSessionPresenterImplementation()
}
}
Basic debugging...
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let identifier = segue.identifier
print("identifier:", identifier)
let dest = segue.destination
print("destination:", dest)
if let navigation = dest as? UINavigationController {
print("dest IS a UINavigationController")
if let vc = navigation.topViewController as? FilterSessionVC {
print("Top Controller IS a FilterSessionVC")
// here you can proceed
vc.presenter = FilterSessionPresenterImplementation()
} else {
print("Top Controller IS NOT a FilterSessionVC")
}
} else {
print("dest IS NOT a UINavigationController")
}
}
Set a breakpoint on the first line, then step through and inspect the results.
Related
I am new to Swift. In my tableview controller I performed segue, and i thought prepare in landing view controller would be called.
// tableview controller
AF.request(url, headers: headers).responseDecodable(of: ProductEach.self) { response in
self.activityIndicator.stopAnimating()
if response.value!.error_message == "invalid product id" {
print("invalid product id")
} else {
//
// do bunch of things with the data I got before performing a segue
//
self.performSegue(withIdentifier: "GotoDetail", sender: self)
}
}
// landing viewcontroller
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard let destinationVC = segue.destination as? TableViewController else { return }
print("prepare called")
}
I can't see the prepare called in the debug console.
Could anyone can tell me the fault i made, please?
Thank you in advance.
Your prepare method is opposite. It should be inside the "from" (not "to") view controller, which is TableViewController, not DetailViewController. And also, you should be comparing segue.destination against DetailViewController, not TableViewController.
// inside TableViewController
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard let destinationVC = segue.destination as? DetailViewController else { return }
print("prepare called")
}
Sorry if the title is a little vague. I'm still learning swift and segues and I have 3 view controllers called EarthViewController, MoonViewController, and JupiterViewController.
These are the segues that work:
EarthViewController -> MoonViewController
MoonViewController -> JupiterViewController
JupiterViewController -> MoonViewController,
and even JupiterViewController -> EarthViewController,
but the unwind segue from MoonViewController -> EarthViewController keeps throwing a Thread 1: Signal SIGABRT error where I have commented //ERROR HERE when trying to go back to the Earth view. Here is the layout and code so far:
EarthViewController (ViewController)
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let des = segue.destination as! MoonViewController
if (segue.identifier == "toMoonView")
{
print("Went to the moon")
}
}
#IBAction func backFromMoon(segue: UIStoryboardSegue){
if let scVC = segue.source as? MoonViewController
{
print ("Back from the Moon to Earth")
}
}
#IBAction func backFromJupiterToEarth(segue: UIStoryboardSegue){
if let scVC = segue.source as? JupiterViewController
{
print ("Back from Jupiter to Earth")
}
}
}
MoonViewController
import UIKit
class MoonViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
//------------------------------------------------------------------------
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let des = segue.destination as! JupiterViewController //<- ERROR HERE
if (segue.identifier == "toJupiterView")
{
print("Went to Jupiter")
}
}
//-----------------------------------------------------------------------
#IBAction func backFromJupiter(segue: UIStoryboardSegue){
if let scVC = segue.source as? JupiterViewController
{
print ("Back from Jupiter to the Moon")
}
}
}
JupiterViewController (Nothing added yet)
import UIKit
class JupiterViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
}
Any help is greatly appreciated! Thank you!
This function in MoonViewController:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let des = segue.destination as! JupiterViewController //<- ERROR HERE
if (segue.identifier == "toJupiterView")
{
print("Went to Jupiter")
}
}
is called both for regular segues and unwind segues. When you are segueing to JupiterViewController then segue.destination is indeed of type JupiterViewController. But when you are unwinding to ViewController, segue.destination is of type ViewController.
In this second case, the force cast as! JupiterViewController crashes because the type is wrong.
One way to fix that is to move the declaration of des inside of the if when you have identified the destination:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "toJupiterView"
{
let des = segue.destination as! JupiterViewController
print("Went to Jupiter")
}
}
I am segueing from a view controller to a tabbarcontroller and I want to pass data. I want to pass "sendAuthor" to the first view controller of the tabbarcontroller.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "FirstVC" {
let vc = (segue.destination as? UITabBarController)?.viewControllers?.first as? CommentProfileViewController
vc?.sendAuthor = sendAuthor!
vc?.Username.text = sendAuthor!
print(sendAuthor!)
}
}
In order to make sure I am getting the right thing, I included a print statement print(sendAuthor!) and I am getting the correct print statement. I also included a print statement in the destination view controller but the print statement returns nil
var sendAuthor: String?
override func viewDidLoad() {
super.viewDidLoad()
print(self.sendAuthor)
}
Your VC is imbedded in a UINavigationController. You need to take that into account as well:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "FirstVC" {
guard let tabbar = segue.destination as? UITabBarController,
let navcon = tabbar.viewControllers?.first as? UINavigationController,
let vc = navcon.topViewController as? CommentProfileViewController
else { return }
vc.sendAuthor = sendAuthor!
vc.Username.text = sendAuthor!
print(sendAuthor!)
}
}
I have a ViewController, "ViewController".
Within this view there is an attribute 'userEmailText.text' that I want to pass along to another view controller, "CreateNewCommunity"
I have a button connected to a segue with identifier 'createCommunitySegue'. I have create the code for when this is tapped:
#IBAction func createCommunityTapped(_ sender: AnyObject) {
self.performSegue(withIdentifier: "createCommunitySegue", sender: self)
}
In my second view controller, "CreateNewCommunity" I have a variable:
var myEmail: String?
and I have started to build the code ready to receive the data from the segue:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "createCommunitySegue" {
let createCommunityController: CreateNewCommunity = segue.destination as! CreateNewCommunity
createCommunityController.myEmail =
}
}
How do I finish this set-up so that the initial 'userEmailText.text' value is passed by "ViewController" through segue 'createCommunitySegue' into "CreateNewCommunity" view controller?
Thanks
Why not just
createCommunityController.myEmail = userEmailText.text
I think your problem is that you have a wrong idea of how to pass data from one vc to another.
The VC that you are passing data to doesn't recieve the data. It is the VC that has the data proactively pass the data to the VC that needs it.
My guess would be that you put this code
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "createCommunitySegue" {
let createCommunityController: CreateNewCommunity = segue.destination as! CreateNewCommunity
createCommunityController.myEmail =
}
}
in the CreateNewCommunity controller! You should instead put the above in ViewController not CreateNewCommunity , and write
createCommunityController.myEmail = userEmailText.text
it should work.
VC1
#IBAction func createCommunityTapped(_ sender: AnyObject) {
self.performSegue(withIdentifier: "createCommunitySegue", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "createCommunitySegue" {
let createCommunityController: CreateNewCommunity = segue.destination as! CreateNewCommunity
createCommunityController.myEmail = userEmailText.text
}
}
VC2
var myEmail: String?
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
print(myEmail)
}
I'm facing the error message:
"UIStoryboardSegue does not have a member named 'identifier'"
Here's the code causing the error
if (segue.identifier == "Load View") {
// pass data to next view
}
On Obj-C it's fine using like this:
if ([segue.identifier isEqualToString:#"Load View"]) {
// pass data to next view
}
What am I doing wrong?
This seems to be due to a problem in the UITableViewController subclass template. It comes with a version of the prepareForSegue method that would require you to unwrap the segue.
Replace your current prepareForSegue function with:
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
if (segue.identifier == "Load View") {
// pass data to next view
}
}
This version implicitly unwraps the parameters, so you should be fine.
Swift 4, Swift 3
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "MySegueId" {
if let nextViewController = segue.destination as? NextViewController {
nextViewController.valueOfxyz = "XYZ" //Or pass any values
nextViewController.valueOf123 = 123
}
}
}
I think the problem is you have to use the ! to unbundle identifier
I have
override func prepareForSegue(segue: UIStoryboardSegue?, sender: AnyObject?) {
if segue!.identifier == "Details" {
let viewController:ViewController = segue!.destinationViewController as ViewController
let indexPath = self.tableView.indexPathForSelectedRow()
viewController.pinCode = self.exams[indexPath.row]
}
}
My understanding is that without the ! you just get a true or false value
For Swift 2.3,swift3,and swift4:
Create a perform Segue at didSelectRowAtindexPath
For Ex:
self.performSegue(withIdentifier: "uiView", sender: self)
After that Create a prepareforSegue function to catch the Destination segue and pass the value:
Ex:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "uiView"{
let destView = segue.destination as! WebViewController
let indexpath = self.newsTableView.indexPathForSelectedRow
let indexurl = tableDatalist[(indexpath?.row)!].link
destView.UrlRec = indexurl
//let url =
}
}
You need to create a variable named UrlRec in Destination ViewController
Swift 1.2
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if (segue.identifier == "ShowDeal") {
if let viewController: DealLandingViewController = segue.destinationViewController as? DealLandingViewController {
viewController.dealEntry = deal
}
}
}
Prepare for Segue in Swift 4.2 and Swift 5.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "OrderVC") {
// pass data to next view
let viewController = segue.destination as? MyOrderDetailsVC
viewController!.OrderData = self.MyorderArray[selectedIndex]
}
}
How to Call segue On specific Event(Like Button Click etc):
performSegue(withIdentifier: "OrderVC", sender: self)
this is one of the ways you can use this function, it is when you want access a variable of another class and change the output based on that variable.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let something = segue.destination as! someViewController
something.aVariable = anotherVariable
}
Provided you aren't using the same destination view controller with different identifiers, the code can be more concise than the other solutions (and avoids the as! in some of the other answers):
override func prepare(for segue: NSStoryboardSegue, sender: Any?) {
if let myViewController = segue.destinationController as? MyViewController {
// Set up the VC
}
}
Change the segue identifier in the right panel in the section with an id. icon to match the string you used in your conditional.
override func prepareForSegue(segue: UIStoryboardSegue?, sender: AnyObject?) {
if(segue!.identifier){
var name = segue!.identifier;
if (name.compare("Load View") == 0){
}
}
}
You can't compare the the identifier with == you have to use the compare() method