Show Label Value on 2nd View - Swift - swift

Since i'm new and a newbie on Swift can someone tell me how I can get the label value on screen 1 to show on screen 2. Thanks
Edit: So I tried the way you told me but for some reason the Label text did not change in View 2. Any help? Thanks

I am passing textFiled data to destViewController to show how segue performs when passing data.
Note: If you want to pass string data to your destVC.You can assign your string like var someValue: String
mainStoryBoard:
MainVC:
#IBOutlet weak var textField: UITextField!
//or you can assign string like var someValue: : String
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let viewController = segue.destination as! destVC
viewController.dataText = textField.text // someValue.text
}
DestVC:
#IBOutlet var label: UILabel!
var dataText = String()
override func viewDidLoad()
label.text = dataText
}
Output:

You already have a segue between ViewController1 and ViewController2 it seems, so now you just need to pass some date from one to another. This can be done in the function prepare(for segue: UIStoryboardSegue, sender: AnyObject?) which is called when you transition from ViewController1 to ViewController2.
The UIStoryboardSegue class has a property called source of type UIViewController and another property called destination which is also a UIViewController.
So, if you define a property on your ViewController2, like so:
var labelValue: String
Then you can pass a value to it in your prepareForSegue defined on ViewController1 like so:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard let viewController2 = segue.destination as? YourViewController2 else {
return
}
viewController2.labelValue = theValueFromViewController1
}
Here is tutorial telling you a bit more (in Objective C though)
And this is also a fine introduction.
Hope that helps you.

I'll consider you have ViewController class VC1 (screen 1) & ViewController class VC2 (screen 2). I see from the screenshot that, you're already using a segue to go from the VC1 to VC2 view.
Now, declare a variable in your VC2 class let's call it labelValue,
class VC2 {
var labelValue: String?
...
}
Whenever you use a storyboard segue to move from one viewcontroller's view to other viewcontroller's view a method named,
func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
will get called if it's overriden in the source viewController class (scene1 in your case). In this method you'd be able to access the destination view controller (scene 2) and it's properties. So for your case you can implement it like this,
class VC1 {
//I have assumed the below label will hold the value which you want to pass it to the scene 2.
var lblResult: UILabel!
......
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// You can access the VC2 instance from the segue
if let vc2 = segue.destinationViewController as? VC2 {
vc2.labelValue = lblResult.text
}
}
Now once you implement the prepareForSegue: method correctly as shown above, you'd be able to get the label's value from scene 1 to labelValue property of scene2.
Do learn more about segues here : More About Segues and Storyboards here.
================================
Edit:
Coming to your edited question, in your View2 viewController, you've declared labelNumber1 as String and not as UILabel, so whenever you pass the value to labelNumber1, the value will be containing in this variable and it will not be shown in the screen since it is just a normal string. So what you can do is, declare the labelNumber1 as UILabel
class View2: UIViewController {
#IBOutlet var labelNumber1: UILabel!
.....
}
and in your prepare for segue in ViewController1 make the following change,
class ViewController1: UIViewController {
.....
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// You can access the VC2 instance from the segue
if let view2 = segue.destinationViewController as? VC2 {
view2.labelNumber1.text = lblResult.text
}
}
However if you still want to keep labelNumber1 as String, and to verify whether the value has been passed from ViewController1 during segue, add below line to viewDidLoad() of View2 ViewController.
class View2: UIViewController {
.....
override func viewDidLoad() {
super.viewDidLoad()
print("labelNumber1: \(labelNumber1)")
}
}
And you can see the printed value of labelNumber1 in the console.
HTH :)

Related

Value not passing between viewControllers

Struggling to get my viewControllers to send value from the main viewController to a second. I want it to happen on a button click, I'm going to get the value from the button and pass it to the new form. But it just isn't working.
Code for main ViewController
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func butClick(_ sender: UIButton) {
NSLog("Button Pressed : %#",[sender .currentTitle])
//var tt = [sender .currentTitle]
// Create the view controller
let vc = TimesTablesViewController(nibName: "TimesTablesViewController", bundle: nil)
vc.passedValue = "xx"
self.performSegue(withIdentifier: "pushSegue", sender: nil)
}
}
Code for second viewController called TimesTablesViewController:
class TimesTablesViewController: UIViewController {
#IBOutlet weak var titleLabel: UILabel!
var passedValue:String = ""
override func viewDidLoad() {
super.viewDidLoad()
titleLabel?.text = "\(passedValue) Times Table"
}
}
I've followed tutorials but can't seem to solve the problem! Thanks for any help!
Replace
self.performSegue(withIdentifier: "pushSegue", sender: nil)
with
self.present(vc,animated:true,completion:nil)
or ( if the current vc is inside a naigation )
self.navigationController?.pushViewController(vc,animated:true)
Using
self.performSegue(withIdentifier: "pushSegue", sender: nil)
is fit with storyboards not xibs and if this your case then you need to use the above line only inside the button action with implementing this method inside the source vc
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "pushSegue" {
if let nextViewController = segue.destination as? TimesTablesViewController{
nextViewController.passedValue = "xx"
}
}
}
I’m assuming that the new view controller is appearing, but you’re simply not seeing the data. If so, you’re evidently using storyboards. The TimesTablesViewController(nibName:bundle:) only works if you’re using XIB/NIBs and manually presenting new view controller.
If you’re really using storyboards, simplify your butClick method:
#IBAction func butClick(_ sender: UIButton) {
NSLog("Button Pressed")
performSegue(withIdentifier: "pushSegue", sender: self)
}
But implement prepare(for:sender:):
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let destination = segue.destination as? TimesTablesViewController {
destination.passedValue = "xx"
}
}
Assuming the above fixes your problem, I might suggest a further simplification. Notably, if your butClick(_:) method is really only calling performSegue, you can segue to this next scene without any #IBAction method at all:
remove butClick(_:) entirely;
remove the connection between the button and the butClick method in IB, on the “Connections Inspector” tab in the right panel; and
control-drag from the button previously hooked up to butClick(_:) to the scene for TimesTablesViewController.
That will simplify your code further.

How to update a label on the next screen?

Say I have two screens. Screen A has a picker and a button, which triggers a segue to screen B, which displays some content depending on the option selected by the picker.
How do I have the information as to what picker was selected in A, passed to B? So far, I have A doing:
#IBAction func pickThing(_ value: Int) {
self.thing = value;
}
Which seems to work; I believe that it is detecting the value and storing it. However, when I try adding #IBOutlet weak var thingLabel: WKInterfaceLabel! to match the label in B, I can only set the value of it when the app first loads.
If I put self.thingLabel.setText("test") in the awake() function, it sets the label to "test", so that works. But changing it to self.thingLabel.setText("thing \(self.thing)") doesn't work - it sets it to whatever self.thing is initialized as, but doesn't change it later. So awake() is not the right method to use. I've also tried putting it in willActivate and in pickThing, but neither of them did anything.
Is there some method that gets called when a screen is switched to? If not, how can I send data from one screen to the next?
For example on ViewController A use this function
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let vc = segue.destination as? ViewControllerB {
vc.thing = self.thing
}
}
Or you can use closures in same methods and callback change from B ViewController on A
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let vc = segue.destination as? ViewControllerB {
vc.clouser = { [weak self] thingB in
guard let `self` = self else { return }
self.thing = thingB
}
}
}
You need to make a variable in view controller B titled something like "parentVC," which would be of view controller A's class. In view controller A's class, you need to call prepare(for segue UIStoryboardSegue, sender: Any?). In this method, you can access the segue's destination property, which would be view controller B. From here you can set view controller B's "parentVC" property to "self," i.e. view controller A. Then in view controller B's class you can access properties of view controller A by using the "parentVC" variable. The code in view controller A's class would look something like this:
func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.destination is ViewControllerB {
let viewControllerB = segue.destination as? ViewControllerB
viewControllerB.parentVC! = self
}
}

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

Delegate using Container View in Swift

I'm developing an app for iPad Pro. In this app, containerView use to add additional views and interact with them.
First, I created a protocol:
protocol DataViewDelegate {
func setTouch(touch: Bool)
}
Then, I created my first view controller
import UIKit
class ViewController: UIViewController, DataViewDelegate {
#IBOutlet var container: UIView!
#IBOutlet var labelText: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
}
func setTouch(touch: Bool) {
if touch == true {
labelText.text = "Touch!"
}
}
}
And finally, I created a view that will be embedded in containerView.
import UIKit
class ContainerViewController: UIViewController {
var dataViewDelegate: DataViewDelegate?
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func touchMe(sender: AnyObject) {
dataViewDelegate?. setTouch(true)
}
}
But for some reason, nothing happened, the first view controller receives nothing in setTouch function.
My question is: In this case, using container, how can I make the communication between two ViewsControllers?
Like #nwales said you haven't yet set the delegate. You should do set the delegate in prepareForSegue function on your first viewController (who contain the viewContainer)
First select the embed segue and set an identifier in the attributes inspector.
Then in the parentViewController implement the func prepareForSegue like this:
Swift 4+:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "the identifier") {
let embedVC = segue.destination as! ViewController
embedVC.delegate = self
}
}
Below:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
if (segue.identifier == "the identifier") {
let embedVC = segue.destinationViewController as! ContainerViewController
embedVC.dataViewDelegate = self
}
}
Looks like you defined the delegate, but have not set the delegate. This happens to me all the time.

SWIFT: No idea how to get back the selected value from a popover to the calling controller

I just going crazy on Swift Popover “return” values. I am new to Objectiv-C as well as SWIFT but I try to focus on SWIFT.
I checked out tutorials around Google and StackOverflow about how to manage iOS popovers, learned a lot but the last peace I couldn’t make it. It is great so see how easy it is made using Swift and Xcode 6, love it, but I could not figure out how to get back the selected value from my popover to my calling view controller.
So here is my problem:
(SIDENOTE: I am using SWIFT and do all using storyboard)
I have created a master ViewController with a button to select currencies. This button opens a “select currency” popover (linked to the CurrencyTableViewController (CTV) by CTRL-Dragging it to the CTV-Controller.
So far so good. The thing is, I have no idea how to get back the selected table row (currency) from the CTV-Table ;-( So I need the selected currency (table row) in the calling ViewController.
This is an excerpt from my ViewController (which is calling the popover)
class ViewController: UIViewController, UIPopoverPresentationControllerDelegate
[...]
// This button is calling the popover
#IBAction func buttonCurrency(sender: AnyObject) {
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if let controller = segue.destinationViewController as? CurrencyTableViewController {
controller.popoverPresentationController?.delegate = self
return
}
}
[...]
Hopefully somebody can help me with that missing last mile how to get back the selected row value back to my ViewController.
Thanks in advance
Cheers
John
I made quick example, hope it helps:
// This is you popover's class
#objc protocol CurrencySelectedDelegate {
func currencySelected(currName: String)
}
class MyPopOverController: UIViewController {
weak var delegate: CurrencySelectedDelegate?
#IBAction func readyButtonPressed(sender: AnyObject) {
// Do what you want
delegate?.currencySelected("Euro/Dollar etc....")
// close popover
}
}
// ViewController
class ViewController: UIViewController, CurrencySelectedDelegate {
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "mySegue" { // your identifier here
let controller = segue.destinationViewController as! MyPopOverController
controller.delegate = self
}
}
}
And remember just declare that currencySelected function in your ViewController.