The problem is label.text value became nil every time all the time accept in viewload. I do not know what is the issue.
I have this code in swift 3 Xcode 8, I have a label as shown below
Label to be set later
then I want to assign the label a value when the view loads as initial value
This is once view loads and it is working fine :)
later on I want to change the label value to the current Date which I would like it to be set when the user moves to another view the comes back , so I made the function open as you say ..
Here is how I call the function
function call from secondViewController
finally I want to set it to those values
last desired values
Do this in your firstviewcontroller ,define a property say :
var x : String?
Now in your secondview controller do this :
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let firstviewcontroller = segue.destination as! FirstViewController
firstviewcontroller.x = "sample value"
// sample value will be displayed on the firstview controller when u move from secondviewcontroller to firstviewcontroller on the label
}
Now in firstviewcontroller set the label in the viewDidLoad() method:
dateItem?.text = x
Note: No need to create another instance of FirstViewController in prepare function because the inbuilt function of UIViewController override func prepare(for segue: UIStoryboardSegue, sender: Any?) is responsible for going from one view controller to other , you just have to compare the identifier
The problem lies in prepare for segue. When you have got your reference using segue.destination to the firstViewController, you don't need to do
s = FirstViewController(), by this you are creating a new instance and not using the one which will actually get initialised during the segue, use firstController.calcPray()
Related
How do I replace a ViewController and also send some parameters?
With the code below, I can only push another ViewController into my current Navigation Stack.
Can we just pop and push another one immediately? Or is there an official to replace for good? Please kindly show me. Thank you.
Perform Segue
performSegue(withIdentifier: "ToNewViewController", sender: self)
Prepare Segue
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let destinationVC = segue.destination as! NewViewController
destinationVC.params = params
}
If you have a navigation controller as your app window root , then you can manage all viewControllers
var vcs = self.navigationController!.viewControllers // get all vcs
vcs = vcs.dropLast() // remove last vc
let vc = // create new VC
vcs.append(vc) // append it
Then alter that array and set it back like this
self.navigationController!.setViewControllers(vcs,animated:true)
OR
You can get the top presented vc with this , then add a method to that vc to do the data replacement and refresh of your UI
I have 3 ViewControllers: ViewController A and ViewController B, and Controller C which is actually a ContainerView consisting of two UIViews
As you can see in the above picture, ViewController C has a clear background such that the "Test Label" can be seen in the UIViews of both ViewController A and B.
When I swipe up from ViewController A to go to ViewController B, I want to be able to perform some animation (fade in/out, translate, change text etc..). Let's say I want to change the text for from "Test Label" to "Some new text", the problem is as soon as I get into ViewController B, I get the "Unexpectedly found nil while unwrapping an Optional value" error.
Why am I getting nil and how can I change the label text properly?
This code seems to make sense but I can't get it right:
let containerViewController = ContainerViewController()
containerViewController.testLabel.text = "Some new text"
I've also tried:
let containerViewController = storyboard?.instantiateViewController(withIdentifier: "containerViewController") as! containerViewController
containerViewController.testLabel.text = "Some new text"
Do I have to add something in ViewController A's override func prepare?
You can give the embed segue from the container to the viewController C an identifier let say embedSegueFromBToC then catch the actual ViewController C in the prepare for segue in the parent controller let say B.
So in B viewController add this:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "embedSegueFromBToC" {
if let viewControllerC = segue.destination as? ViewControllerC {
viewContrllerC.loadViewIfNeeded() // you might need this since the need to access the testLabel which a UI component that need to be loaded
viewControllerC.testLabel.text = "Some new text"
}
}
}
Correct, you have to use the prepare(for segue:..) override in your originating view controller, it will be passed the instance of ViewController B as the segue.destination.
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
{
if let viewControllerB = segue.destination as? ViewControllerB
{
viewControllerB.testLabel.text = "Some new text"
}
}
Check out this tutorial for more information: https://learnappmaking.com/pass-data-between-view-controllers-swift-how-to/
This question already has answers here:
Changing label text of second ViewController upon clicking button in first ViewController
(4 answers)
Closed 6 years ago.
When using the prepare (forSegue) method to pass data to the destination view controller of a segue, all members of the destination VC are nil. Thus, my program crashes when trying to access these members.
My code in the source view controller:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "Second2DetailEdit"{
var detailVC = segue.destination as! DrinkDetailViewController
detailVC.headerLabel.text = "Edit Drink"
}
//...
}
The VC itself is not nil. Only all members of the VC. Did I forget something?
This does only occur in my new Swift 3 project. Similar code in my Swift 2 projects have no problems.
Thanks in advance.
The destination view controller's view is not created yet and that's why all IBOutlets are nil. Try sending the information you need in normal properties like Strings and in ViewDidLoad of the destination, update your view.
The best way around this is to create a variable in your second view controller and set the text to that instead.
Then once the vc has initialized you can set the headerLabel.text to the new variable in viewDidLoad
I would suggest safely unwrapping your detailVC rather than force unwrapping...
if segue.identifier == "Second2DetailEdit" {
if let detailVC = segue.destination as? DrinkDetailViewController {
detailVC.headerLabel.text = "Edit Drink"
}
}
You'll have an easier time setting properties on the destinationVC and passing info to those rather than trying to do it through UILabels...
I have a TableViewController embedded in a ViewController. My UITableView has toggles. When one of these toggles are toggled I need my number on the ViewController to increase by 1. The issue I am having is not being able to get the text to change. I have supplied a screenshot to help better illustrate.
What I have tried doing is setting a variable var colorViewController: ViewController? in the TableViewController and then trying to set the text from there using colorViewController?.displayNumber.text = screenCount when toggling a toggle. screenCount is the variable that increasing as the toggles are toggled.
How are you setting your colorViewController variable?
You need to set it to the current instance of your ViewController in your ViewController's prepare for segue.
First, you'll need to give the embed segue an identifier. Select the segue in the storyboard and give it an identifier, say ColorPickerTableViewControllerSegue.
Then handle this segue in your ViewController (this is Swift 3 code):
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "ColorPickerTableViewControllerSegue" {
if let colorPickerTableViewController = segue.destination as? ColorPickerTableViewController {
colorPickerTableViewController.colorViewController = self
}
}
}
This question already has answers here:
Passing data between view controllers
(45 answers)
Closed 6 years ago.
I'm making a new application.
If I have a text field on one view controller and a label on another (both View Controllers in ViewController class), How can i type something in on the text field and then take me to the next ViewController and display the text?
In the source controller in prepare for segue you set a property on your destination controller:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let detailViewController = segue.destination as? DetailViewController {
detailViewController.titleText = mylabel.text
}
}
In your destination controller's view did load you assign this property to your label field.
var titleText = ""
override func viewDidLoad() {
super.viewDidLoad()
label.text = titleText
}
Note you cannot assign directly to your label in prepareForSegue because the label is not guaranteed to have been initialized until ViewDidLoad has been called. Thats why the value goes into a property. Proper model view separation also dictates that one controller shouldn't be writing to another controller's view anyways.