Pass a string to a second view controller - ios

I'm trying to pass a string to a second view controller. The string is the title of the new view controller.
To pass the string I can use 2 solutions and both solutions work correctly but for me is not so clear the difference. Can someone explain me the differences?
Here the first solution:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if (segue.identifier == "settime") {
let svc = segue.destinationViewController as! timeSetting;
//Assign the new title
svc.toPass = "New Title"
}
}
Here the second solution:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if (segue.identifier == "settime") {
let svc = segue.destinationViewController as? timeSetting;
//Assign the new title
svc!.toPass = "New Title"
}
}
The variable toPass is defined in this way in the second viewController:
var toPass:String = "Title"

Both of your code is working and it works in the same way.
The only difference is about the optional casting.
Optional in Swift

Both solutions will perform the same action. In my opinion, the first solution is preferred because it express your intent more precisely.
By stating let svc = segue.destinationViewController as! timesetting you state that the destination view controller is certain to be of the type timesetting.
The second form tests to see if the destination view controller is of the type timeSetting. If it is, then the variable svc will have a non-nil value.
If you were to define another segue of the same name that presents a different type of view controller, then both solutions will fail; the first one on the as! clause and the second one when you try to unwrap svc!, which would be nil.

They are the same.
If there is a difference, it is the time of unwrap the optional value. In the first solution, the type of svc is timeSetting. In the second solution, the type of svc is timeSetting?.

Both will work but in my opinion the best way is to unwrap the optional like the following:
if let svc = segue.destinationViewController as? timeSerting { svc.toPass = "xx" }

Related

Populate textfield.text after segue

I have a show-type segue. I want destinationViewController nameTextField to contain some text in it when segue is performed. I tried doing:
override func prepare (for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "ToEditScreen" {
let svc = segue.destination as! EditViewController
svc.nameTextField.text = cars[selectedIndex!].name //crashes
svc.nameString = cars[selectedIndex!].name
}
}
The error I get is: Unexpectedly found nil while implicitly unwrapping an Optional value.
I know that cars[selectedIndex!].name is not nil.
If I delete the textfield line everything is fine and nameString does get its value which is equal to cars[selectedIndex!].name. I know I can do:
nameTextField.text = randomString
but it seems like an extra step. Can I populate textfield.text from original ViewController?
You can add a string variable to the destination vc and set it there or
let svc = segue.destination as! EditViewController
svc.loadViewIfNeeded() // add this line
svc.nameTextField.text = cars[selectedIndex!].name

Value of type 'UIViewController' has no member 'jsonfile' named JSON

I currently have a button set to go to a TableViewController but decided I wanted to embed that TableViewController in a TabBarController. I am running into an error while trying to pass it to the UITabBarController.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "showListSegue") {
let tabBarController = segue.destinationViewController as! UITabBarController
tabBarController.selectedIndex = 0 // choose which tab is selected
let des = tabBarController.selectedViewController!
des.jsonfile = self.jsonfile
}
}
In the last line of code, des.jsonfile = self.jsonfile, I am getting the error...
Value of type 'UIViewController' has no member 'jsonfile'
I am trying to pass the jsonfile to the TableViewController which is now embedded in the UITabBarController. How can this be done? I have this variable in the TableViewController is was getting passed to but now that I threw this TabBarController in the mix I am getting all confused.
I also tried to create a Cocoa file for the TabBarcontroller and set the variable var jsonfile : JSON! but that did not work either. (That is the variable in my TableViewController that I want to pass it to) Please help. Thank you.
You need to let the compiler know that selectedViewController is a type with the member jsonFile. Also, you should check that it actually is existing and of the correct class at runtime. Here's the kind of pattern you should be using:
class JSONDisplayController: UIViewController {
var jsonfile: String
}
func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "showListSegue") {
guard let tabBarController = segue.destinationViewController as? UITabBarController else {
preconditionFailure("Unexpected destination.")
}
tabBarController.selectedIndex = 0 // choose which tab is selected
guard let des = tabBarController.selectedViewController as? JSONDisplayController else {
preconditionFailure("Unexpected selection.")
}
des.jsonfile = jsonfile
}
}

Error "cannot assign a value of type" in prepareForSegue method (Swift, Xcode 6)

I just want to make a segue by an example here http://www.codingexplorer.com/segue-uitableviewcell-taps-swift/
But when I made this code:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == blogSegueIdentifier {
if let destination = segue.destinationViewController as? specialitiesViewController {
if let cellIndex = tableView.indexPathForSelectedRow()?.row {
destination.formuleName = formulesList[cellIndex]
}
}
}
}
Appeared error called:
cannot assign a value of type '(Formules)' to a value of type String"
this is a class which contents a data for formuleList
formuleList is an array with a list of cell names
how to remove error?
Thank u for your help.
The way that this segue block works is you are basically telling the UI that I'm going to segue to the next view controller
if let destination = segue.destinationViewController as? specialitiesViewController - says that the ViewController we are going to is of custom type specialitiesViewController
My assumption would be that in your specialitiesViewController you have a variable called forumlaName that is of type String and that your formulesList is of type [Formules] - and as such this assignment is invalid.
You are trying to assign a specific Formules to a String and thus occurs your error.
Fix choices would be to make sure the type Formules implements one of the String protocols such as Printable that allows it to be represented as a string. Alternativley perhaps you have something like a name variable inside that is a string
Depending on the version of Swift you are using you could do something like:
extension Formules : Printable {
override public var description: String {
return "TEST"
}
}
but with out more actual code info i can't tell you if this will actually work

Passing data to another ViewController in Swift

Before I begin, let me say that I have taken a look at a popular post on the matter: Passing Data between View Controllers
My project is on github https://github.com/model3volution/TipMe
I am inside of a UINavigationController, thus using a pushsegue.
I have verified that my IBAction methods are properly linked up and that segue.identifier corresponds to the segue's identifier in the storyboard.
If I take out the prepareForSegue: method then the segue occurs, but obviously without any data updating.
My specific error message is: Could not cast value of type 'TipMe.FacesViewController' (0x10de38) to 'UINavigationController' (0x1892e1c).
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
if segue.identifier == "toFacesVC" {
let navController:UINavigationController = segue.destinationViewController as! UINavigationController
let facesVC = navController.topViewController as! FacesViewController
facesVC.balanceLabel.text = "Balance before tip: $\(balanceDouble)"
}
}
Below is a screenshot with the code and error.
side notes: using Xcode 6.3, Swift 1.2
A couple of things:
1: change your prepareForSegue to
if segue.identifier == "toFacesVC" {
let facesVC = segue.destinationViewController as! FacesViewController
facesVC.text = "Balance before tip: $\(balanceDouble)"
}
2: add a string variable to your FacesViewController
var text:String!
3: change the FacesViewController viewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
balanceLabel.text = text
}
The reasons for all the changes: the segue destinationViewController is the actual FacesViewController you transition to -> no need for the navigationController shenanigans. That alone will remove the "case error", but another will occur due to unwrapping a nil value because you try to access the balanceLabel which will not have been set yet. Therefore you need to create a string variable to hold the string you actually want to assign and then assign that text in the viewDidLoad - at the point where the UILabel is actually assigned.
Proof that it works:
4: If you want display two decimal places for the balance you might change the String creation to something like (following https://stackoverflow.com/a/24102844/2442804):
facesVC.text = String(format: "Balance before tip: $%.2f", balanceDouble)
resulting in:

segue with Dictionary SWIFT

Another question which just should be simple but I am again stumped
I have created a dictionary from a log in.
It is full of values. I now want to segue to a new View controller and take the data with me
So I set up
typealias JSONDict = [String:AnyObject]
func prepareForSegue(segue: UIStoryboardSegue, sender: JSONDict!) {
if (segue.identifier == "toHome"){
var svc = segue.destinationViewController as! OtherViewController
svc.toPass2 = parsed!
Parsed shows as JSONDict - all seems well
Over on OtherViewcontroller I set up to catch it:
var toPass2:JSONDict = JSONDict()
this builds for me quite happily and segues as expected.
But when I
println("check data: \(toPass2)")
I get [:]
Nothing.
It seems to me I have built it - but nothing is coming. I could pass individual values - but all I rally want to do is bring the dictionary with me
I also tried the same thing with the unparsed data string - and this too got me a zero result.
Any help appreciated
in your OtherViewController try this:
class OtherViewController: UIViewController {
var toPass2: JSONDict? {
didSet {
println(toPass2)
}
}
}

Resources