Cannot find `ViewController` in prepare for segue - swift

I´m trying to pass data from one ViewController to another. But when I try to set the destinationVC Xcode doesn't recognize the ViewController. I get no autocomplete for the DataRecieverViewController I get autocomplete for the other ViewCOntrollers When I write it in manually, I get no errors, but no data is passed.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == passDataSegue {
let destination = segue.destination as! DataRecieverViewController //Xcode doesn't recognize this VC. I get no autocomplete.
destination.data1 = data1
}
}

override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
if (segue.identifier == "identfiername")
{
let destination = segue.destination as! DataRecieverViewController
destination.data1 = data1
}
}
for you the identifier name is passDataSegue, When you work with segues please cross check the seguename and viewcontroller name once more to avoid erorrs.

About autocomplete try to save the file DataRecieverViewController and build your project it is a common bug of Xcode.
About data pass
Are you sure you are getting to the right instance of DataRecieverViewController, not the general class?
Is it embedded in a NavigationController ot UITabBarController ?
if Yes you have to get the right instance.
If embedded in UITabBarController
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
if (segue.identifier == passDataSegue)
{
let tabBar = segue.destination as! UITabBarController
let controller = tabBar.viewControllers?.first(where: { $0 is DataRecieverViewController }) as? DataRecieverViewController
controller.data1 = data1
}
In case of UINavigationController
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
if (segue.identifier == passDataSegue)
{
let NavBar = segue.destination as! UINavigationController
let NavC = NavBar.viewControllers?.first(where: { $0 is DataRecieverViewController }) as? DataRecieverViewController
let controller = NavC.rootViewController as? DataRecieverViewController
controller.data1 = data1
}

Related

(Swift) how to use Segue pass textField to TableViewCell under another ViewController?

I wonder how to pass the textField to my customTableViweCell. Please, someone help me! enter image description here
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "segue" {
let nextVC = segue.destination as! UINavigationController
let dest = nextVC.topViewController as! ViewController
let ind = sender as! customTableViewCell
let nTxt = nameTxt.text?.description
let pTxt = phoneTxt.text?.description
let eTxt = emailTxt.text?.description
let dTxt = dobTxt.text?.description
ind.lb1 = "\(nTxt!)"
ind.lb2 = "\(pTxt!)"
ind.lb3 = "\(eTxt!)"
ind.lb4 = "\(dTxt!)"
}
}
segue.destination will contain the destination view controller. You should cast it to your custom view controller that will be presented. That view controller, should have properties defined that will be used to build that view. You should set those properties in prepare so that when the destination view controller loads the view, those properties can be used to update the view components. Here's an example.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "segue" {
let dest = segue.destination as? YourCustomViewController
dest?.customProp = someValue
}
}

Swift Audio passing to another ViewController

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "stopRecording" {
let playSoundsVC = segue.destination as! PlaySoundsViewController
let recordedAudioURL = sender as! URL
playSoundsVC.receivedAudio = recordedAudioURL
}
}
The question is that my Xcode generating error
Value of type 'PlaySoundsViewController' has no member 'receivedAudio'
For this to work the destinationVC should look like this
class PlaySoundsViewController:UIViewController {
var receivedAudio:URL?
.....
}

Add two guard let in a prepare for segue function

I'm trying to build my first app with three tableViews which are hierarchical. The middle VC has two guard let in one prepare for segue function.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard let destination = segue.destination as? AddMemberViewController else {
return
}
destination.club = club
guard let Destination = segue.destination as? TransactionViewController, let selectedRow = self.tableViewMember.indexPathForSelectedRow?.row else {
return
}
Destination.member = members[selectedRow]
}
That's how it looks like. Can I fix this, that both func get used by my app, because it just uses the one on the top.
The problem is if you want to segue to TransactionViewController the function already returns because segue.destination is not AddMemberViewController.
Instead you should give your segues different identifiers and ask for them in prepareForSegue. Something like this:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "AddMemberVCSegue" {
guard let destination = segue.destination as? AddMemberViewController else {
return
}
destination.club = club
}
if segue.identifier == "TransactionVCSegue" {
guard let Destination = segue.destination as? TransactionViewController, let selectedRow = self.tableViewMember.indexPathForSelectedRow?.row else {
return
}
Destination.member = members[selectedRow]
}
}
Just replace guards with if lets:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let destination = segue.destination as? AddMemberViewController {
destination.club = club
} else if let destination = segue.destination as? TransactionViewController, let selectedRow = self.tableViewMember.indexPathForSelectedRow?.row {
destination.member = members[selectedRow]
}
}
prepare(for is called for one specific segue, so executing both guard let after another is unnecessarily expensive.
Usually you are checking the identifier of the segue with a switch statement, replace the literal identifiers with your real values
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
switch segue.identifier {
case "memberSegue":
let destination = segue.destination as! AddMemberViewController
destination.club = club
case "transactionSegue":
guard let selectedRow = self.tableViewMember.indexPathForSelectedRow?.row else { return }
let destination = segue.destination as! TransactionViewController
destination.member = members[selectedRow]
default: break
}
}

what is the collectionView form of indexPathForSelectedRow?

I'm attempting to create a variable "indexx" that will be segued to my next tableController. indexx will hold the indexPath of the selected cell from my collectionView, however, I am unsure which property to use. I am vastly more familiar with tableController properties so I'm having difficulty finding a successful solution to this piece of code. Would you happen to know my error?
As a quick note - foodcv is my collectionView and numberr is the variable in the second destination controller.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let destViewController = segue.destination as? foodtable {
let indexx = self.foodcv.indexPath(for: foodcell)
destViewController.numberr = indexx
}
}
let numberr : IndexPath = []
Maybe it's too late, but here you go:
Swift 4
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let destViewController = segue.destination as? foodtable {
let indexPaths : NSArray = foodcv.indexPathsForSelectedItems! as NSArray
let indexx : IndexPath = indexPaths[0] as! IndexPath
destViewController.numberr = indexx[selectedindexPath.row]
}
}
Use this modified implementation,
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let destViewController = segue.destination as? foodtable {
let indexx = self.foodcv.indexPathForCell(sender as! UICollectionViewCell)
destViewController.numberr = indexx
}
}

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
}
}