Problem with cast on the function prepareForSegue - swift

I have an error with my segue. When I click on the information button the application crashes. In the title View I have multiple segues. The first one is for send array to the register view and the others is for opening my information Pop Up.
The message error is:
And this is the main StoryBoard:
How do I fix this?

If you have 2 segues then you need to differentiate them with the identifier
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifer == "toPopUp" {
if let yourVC = segue.destination as? YourPopController {
// set data
}
}
else {
if let yourVC = segue.destination as? RegisterViewController {
// set data
}
}
}

Related

Segue from an UITableViewController to another one issue

I am trying to segue 2 ViewControllers of of UI Table type, but it shows me an error "Thread 1: signal SIGABRT", here the code:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showPlates"{
if let indexPath = self.tableView.indexPathForSelectedRow{
let selectedRecipe = self.recetas[indexPath.row]
let destinationViewController = segue.destination as! PlateViewController
destinationViewController.recetas = [selectedRecipe]
}
}
}
Probably you haven't set a class (PlateViewController) for desired destination ViewController in your storyboard (I guess in Main.storyboard)

connect segue to Navigation control

Before I used a Segue to transfer data between to view controllers.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "Edit List" {
if let currentTodo = todoReadyForEditing, let editControler = segue.destination as? ListPageController {
editList.prepare(for: currentList)
}
Now the plan is changed I should transfer the data from the first view controllers to a tableViewController. Since I want to have a navigation bar to the tableViewController page, I added a navigationBarController before it.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "Edit List" {
if let currentTodo = todoReadyForEditing, let editControler = segue.destination as? ListTableViewController {
editList.prepare(for: currentList)
}
The problem is when I connected segue directly to UITableViewController, everything is work, same as before that I have two view controllers, but the navigation bar is hidden, which I don't want. As I read, apparently i have to connect the segue first to the navigationViewController, but when I did not, the data won't transfer to the table view controller.
Is there any suggestion? Thanks for your help in advance
Destination of segue is UINavigationController, but you can work with its topViewController property which is your controller
guard let navCon = segue.destination as? UINavigationController,
let controller = navCon.topViewController as? ListTableViewController else { fatalError("Segue wasn’t set right") }
Anyway, I would suggest you don’t use segues and create your UINavigationController with embedded controller programmatically

Accessing methods, actions and/or outlets from other controllers with swift

I'm working on a macOS project where I have a split view containing 2 other ViewControllers and I can't figure out how to access the ViewControllers from my primary window's ViewController.
this is the setup:
Basically what I'm trying to do is use the Button in my ViewController on the top-left to access the Label in my SectionController on the right, which is embedded in my split view.
Since I can't create an IBAction or IBOutlet for a control in a different ViewController, I can't figure out how to get these to be connected. My current workaround has been to have a property on my AppDelegate and then access the main shared application delegate, but that feels hacky and won't scale. I'm completely lost as to how to proceed. I'm ok with using a function to pass data or whatever to the other ViewController(s).
I'm using Swift 4 with Xcode 9 (beta).
Any ideas?
Of course you can't create IBAction or IBOutlet for a control in a different ViewController!!
But simply each view controller in the hierarchy has a reference for its child view controllers.
Method 1:
#IBAction func buttonTapped(_ sender: Any) {
let splitViewController = self.childViewControllers[0] as! YourSplitViewController
let targetViewController = splitViewController.childViewControllers[0] as! YourTargetViewController
targetViewController.label.text = "Whatever!"
}
Method 2:
It may be better if you took a reference for each child controller in your "prepare for segue" method
ContainerViewController:
var mySplitViewController: YourSplitViewController?
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "splitViewSegue" {
self.mySplitViewController = segue.destination as! YourSplitViewController
}
}
YourSplitViewController:
var aViewController: YourFirstViewController?
var bViewController: YourSecondViewController?
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "aViewSegue" {
self.aViewController = segue.destination as! YourFirstViewController
} else if segue.identifier == "bViewSegue" {
self.bViewController = segue.destination as! YourSecondViewController
}
}
So you can access it like that in your container view controller:
#IBAction func buttonTapped(_ sender: Any) {
self.mySplitViewController.firstViewController.label.text = "Whatever!"
}

How to identify if a scene has been opened by a certain segue in Swift?

I have a scene which I open with this segue.
//pass all retrived info from signup field over to the login scene to facilitate user experience
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if (segue.identifier == "showLoginController") {
let svc = segue.destinationViewController as! LoginController;
print("pass data over to next viewcontroller")
}
}
This segue goes back to the Login screen where I want to set some values. However when the Login screen has not been loaded by segue "showLoginController", some fields should be empty.
How can I identify if LoginScene has been opened by a certain segue and set values accordingly?
In your LoginController view controller add this:
var fromSegue = false
And in prepareForSegue:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if (segue.identifier == "showLoginController") {
let svc = segue.destinationViewController as! LoginController;
svc.fromSegue = true
print("pass data over to next viewcontroller")
}
}
And then in your LoginController you can check fromSegue.
You can know the segue from the previous scene, in the sender scene, implement prepareForSegue() method to detect the sender

How to know which segue was used using Swift?

I have a main viewController and a detailsViewController. The detailsViewController has 2 buttons. Both buttons are segues back to the main controller but I want to customize the main viewController based on which segue was used. What is the best way to check which segue was used to reach a viewController so that the main viewController can be customized depending on that? - if segue1 leads to the the main viewController then I want label1 hidden. if segue2 leads to the main viewController, then I want label2 hidden.
In Main View Controller create a variable , something like
var vcOne : Bool = true
Now in DetailsViewController
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if segue.identifier == "segue_one"
{
let mainVC : MainViewController = segue.destinationViewController as! MainViewController
secondVC.vcOne = true
}
else if segue.identifier == "segue_two"
{
let mainVC : MainViewController = segue.destinationViewController as! MainViewController
secondVC.vcOne = false
}
}
Now in MainView Controller
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
//Now check here for which segue
if(vcOne)
{
// implement for button one click
}
else
{
// implement for button two click
}
}
Hope it helps you
I'd do something like to check which segue was used. You have to set an identifier to the segue in the storyboard though!
func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "yourIdentifier" {
let yourVC = segue.destinationViewController as? yourViewController
//do magic with your destination
}
}
There is a option for setting Identifier for segue. This should be unique identifier. So that you can identify which segue is activated.
Ex:
func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "Identifier1" {
let firstVC = segue.destinationViewController as? FirstViewController
} else if segue.identifier == "Identifier2" {
let secondVC = segue.destinationViewController as? SecondViewController
}
}