How to access variable from one class in another? Swift Code - xcode

I am having an issue getting one simple variable from one class to another and it is beyond extremely frustrating :/...
Here is the deal I have two view controller classes named: ViewController.swift and ViewController2.swift
ViewController.swift is linked to a storyboard that has sort of an inventory bag that I have placed which is just an image. Then there is an #IBAction for when you click on the bag it opens up and the second storyboard pops into view. This is controlled by ViewController2.swift. All I am looking to do is simply pass the center of the bag image from ViewController to ViewController2 but I can't seem to get it to work any help would be greatly appreciated.
class ViewController: UIViewController {
#IBOutlet weak var InventoryBag: UIImageView!
var bagCenter:CGPoint = CGPoint(x: 0, y: 0)
override func viewDidLoad() {
super.viewDidLoad()
#IBAction func InventoryButtonTapped(sender: UIButton) {
self.InventoryBag.image = UIImage(named: "backpackimageopen")
bagCenter = self.InventoryBag.center
func transferViewControllerVariables() -> (CGPoint){
return bagCenter
}
When I print the bagCenter from this ViewController it works properly and gives me a correct value. So the bagCenter variable I would like to somehow pass over to ViewController2.swift.
Here is what I tried from ViewController2.swift but it never seems to work and always gives me a 0 rather than the actual value.
class ViewController2: UIViewController {
#IBOutlet weak var HideButton: UIButton!
#IBOutlet weak var InventoryCollection: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
//Load the center of the inventory bag to this view controller to align the hide button.
var bagCenter = ViewController().transferViewControllerVariables()
}
But when I do this it always results in a 0 and I don't get the actual coords of the bag that are showing up in ViewController1.

Create a following variable in ViewController2
var previousViewController: ViewController!
Add following line of code in your ViewController Class
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?){
if segue.destinationViewController .isKindOfClass(ViewController2){
let vc2 = segue.destinationViewController as! ViewController2
vc2.previousViewController = self
}
}
Now in viewDidLoad method of ViewController2 you can access bagCenter like below:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
var bagCenter = previousViewController.transferViewControllerVariables()
}

Try this in view Controller
class ViewController: UIViewController {
#IBOutlet weak var InventoryBag: UIImageView!
var bagCenter:CGPoint = CGPoint(x: 0, y: 0)
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#IBAction func InventoryButtonTapped(sender: AnyObject) {
self.InventoryBag.image = UIImage(named:"MAKEUP_SHARE.jpg")
bagCenter = self.InventoryBag.center
performSegueWithIdentifier("Go", sender: self)
}
// Give a segue identifier in storyboard
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "yoursegueidentifier" {
let dvc = segue.destinationViewController as? ViewController2
dvc!.bagCenter = bagCenter
}
}
}
and in view controller2
class ViewController2: UIViewController {
var bagCenter:CGPoint!
override func viewDidLoad() {
super.viewDidLoad()
print(bagCenter)
}
}

Related

How to call function in NSViewController?

class CustViewController: NSViewController {
#IBOutlet weak var tableView: NSTableView!
#IBOutlet weak var statusLabel: NSTextField!
fileprivate var selectedOptionFromMenu = ""
#objc var contacts:[Person] = []
#objc var backUpContacts:[Person] = []
#IBAction func printCustomers(_ sender: Any?) {
I would like to call the printCustomers function from another class (NSWindowController). How is this coded in the NSWindowController class?
I tried the following:
let printAction = CustViewController.printCustomers(<#T##self: CustViewController##CustViewController#> )
but don't know how to code argument in this and this may be not be the way to do this?
I used an observer to notify when to run the code in the ViewController
The following is the code I used to accomplish this:
In the main WindowController
public let printNotification = Notification.Name("printNotification")
#IBAction func cashToMePrinting(_ sender: Any?) {
switch activeWindow {
case activeView.customerView:
let printCustNC = NotificationCenter.default
printCustNC.post(name: printNotification, object: nil)
default:
print()
}
}
Added the #IBAction to the responder chain using toolbar print item
Then in the ViewController I added:
#objc func reactToNotification(_ sender: Notification) {
// Do what you need, including updating IBOutlets
printCustomers(Any?.self)
}

swift 4- Save the last data of a text field in a label so that they are displayed when the app is restarted

I have a problem, I want to create a small app in which data in a formula can be charged.
Currently the data from three ViewControllers and one PickerViewController will be given back to the first ViewController.
That works very well too.
Now I want that the data at the start not on "nil" set but have a certain value.
Thereafter, the data entered last should reappear when the app is restarted.
I would like to apologize for my english, it is not my preferred language ...
Here is a part of my code how I wrote it
Main ViewController:
import UIKit
class RecivingViewController: UIViewController, SendDataBack, SendDataBack2, SendDataBack3, SendDataBack4 {
#IBOutlet weak var recivingData: UILabel!
#IBOutlet weak var recivingData2: UILabel!
#IBOutlet weak var recivingData3: UILabel!
#IBOutlet weak var recivingData4: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
func userData(data: String) {
recivingData.text = data
}
func userData2(data: String) {
recivingData2.text = data
}
func userData3(data: String) {
recivingData3.text = data
}
func PickerData(data: String){
recivingData4.text = data
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "view1" {
let SendingVC: SendingViewController = segue.destination as! SendingViewController
SendingVC.delegate = self
}
if segue.identifier == "view2" {
let SendingVC2: Sending2ViewController = segue.destination as! Sending2ViewController
SendingVC2.delegate = self
}
if segue.identifier == "view3" {
let SendingVC3: Sending3ViewController = segue.destination as! Sending3ViewController
SendingVC3.delegate = self
}
if segue.identifier == "picker" {
let SendingVC4: PickerViewController = segue.destination as! PickerViewController
SendingVC4.delegate = self
}
}
}
one of the other ViewControllers:
import UIKit
protocol SendDataBack {
func userData(data: String)
}
class SendingViewController: UIViewController {
#IBOutlet weak var DataTxt: UITextField!
var delegate: SendDataBack? = nil
#IBAction func done(_ sender: Any) {
if delegate != nil {
if DataTxt.text != nil {
let data = DataTxt.text
delegate?.userData(data: data!)
dismiss(animated: true, completion: nil)
}
}
}
In order to see data after app is restarted you should use user defaults.
For saving data
UserDefaults.standard.set(newValue, forKey: "data")
For loading data in your view controller, if it's first load, when data is nil
UserDefaults.standard.string(forKey: "data")

Use of unresolved identifier 'self'

I am working on a Mac OS X application with Swift.
This is my first time and I thought it would be the same as it is on iOS.
So I got this error (in the title) on this code:
import Cocoa
import AppKit
class LoginViewController: NSViewController {
#IBOutlet weak var emailTextField: NSTextField!
#IBOutlet weak var passwordTextField: NSSecureTextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func viewDidAppear() {
}
super.viewDidAppear()
if NSUserDefaults.standardUserDefaults().valueForKey("uid") != nil && CURRENT_USER!.authData != nil
{
self.logoutButton.hidden = false
}
}
func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
func loginAction(sender: AnyObject)
{
let email = self.emailTextField.text
let password = self.passwordTextField.text
...
}
}
What do I have to write instead of self?
Using self is correct. Try using the property stringValue instead of text.
Here is the code that worked for me:
#IBOutlet weak var emailTextField: NSTextField!
#IBAction func sendTapped(sender: AnyObject) {
let email = self.emailTextField.stringValue
print(email)
}

Pass data via segue between 2 view controllers and update labels

I am trying to pass var projectNumber from ViewController to Project1ViewController via segue and save it as var projectNum. Then use projectNum to update the labels in Project1ViewController. The segue and action/outlets are all set up. The app runs fluently (no errors), however, projectNum in Project1ViewController is not getting the projectNumber value and making it projectNum.
How do I pass the projectNumber value from ViewController to Project1ViewController and save it in projectNum? I've seen tutorials that describe similar actions being performed via delegates, but I'm unsure if delegates are applicable to my question. Any feedback helps.
ViewController
import UIKit
class ViewController: UIViewController{
var projectNumber:String = ""
#IBOutlet var projectButton1 : UIButton!
#IBOutlet var projectButton2 : UIButton!
#IBOutlet var projectButton3 : UIButton!
#IBOutlet var projectButton4 : UIButton!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func updateLabels(sender: UIButton!) {
projectNumber = String(sender.tag)
println(projectNumber)
sender.setTitle(String(projectNumber), forState: UIControlState.Normal)
func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
//if user presses Project 3921 button
if segue.identifier == "Project3921Segue"
{
if var destinationVC = segue.destinationViewController as? Project1ViewController{
destinationVC.projectNum = projectNumber
}
}
//if user presses Project 3922 button
else if segue.identifier == "Project3922Segue"
{
if var destinationVC = segue.destinationViewController as? Project1ViewController{
destinationVC.projectNum = projectNumber
}
}
//if user presses Project 3923 button
else if segue.identifier == "Project3923Segue"
{
if var destinationVC = segue.destinationViewController as? Project1ViewController{
destinationVC.projectNum = projectNumber
}
}
//otherwise user presses Project 3924 button
else if segue.identifier == "Project3924Segue"
{
if var destinationVC = segue.destinationViewController as? Project1ViewController{
destinationVC.projectNum = projectNumber
}
}
}
}
}
Project1ViewController
import UIKit
class Project1ViewController: UIViewController {
var projectNum:String!
#IBOutlet var projectNumLabel: UILabel!
#IBOutlet var projectNumTitle: UINavigationItem!
override func viewDidLoad() {
super.viewDidLoad()
projectNumLabel.text = projectNum
projectNumTitle.title = projectNum
println(projectNum)
// Do any additional setup after loading the view.
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Thanks!
You are defining prepareForSegueinside the button action function. It is a ViewController function to be overridden.
Your solution can be way more simpler:
class ViewController: UIViewController{
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if var destinationVC = segue.destinationViewController as? Project1ViewController{
destinationVC.projectNum = segue.identifier
}
}
}
Note you do not need the button outlets, since you just configure them in the storyboard with the proper segue identifier. Unless you need some other custom action to be triggered by the buttons.
And:
class Project1ViewController: UIViewController {
var projectNum:String!
#IBOutlet var projectNumLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
projectNumLabel.text = projectNum
self.title = projectNum
println(projectNum)
}
}
Note I just set the title property of Project1ViewController in order to present the projectNum as the title in the navigation controller. I assume your controllers are embedded in a navigation controller and the ViewController's buttons has show segues to Project1ViewController.

Updates Labels in Swift when using popoverController

I have a question about swift,
I made a popover controller in a UIViewController,which display a list of books
and when the user click on one of the books, the label on the viewController should be updated with the name of the selected book.
But in my case when I select a name of a book, the label does not update
here is the code :
// View Controller
import UIKit
class ViewController: UIViewController,UIPopoverControllerDelegate {
var popoverController : UIPopoverController? = nil
#IBOutlet var bookName : UILabel
var BookNameString : String?{
didSet{
configureView()
}
}
func configureView() {
// Update the user interface for the detail item.
if let detail = self.BookNameString {
if let label = bookName {
label.text = detail
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
#IBAction func Click(sender : UIButton) {
var tableView:TableViewController = TableViewController(style: UITableViewStyle.Plain)
var popoverContent:UINavigationController = UINavigationController(rootViewController: tableView)
self.popoverController = UIPopoverController(contentViewController: popoverContent)
self.popoverController!.delegate = self
self.popoverController!.presentPopoverFromRect(sender.frame, inView: self.view, permittedArrowDirections: UIPopoverArrowDirection.Any, animated: true)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
and here is the code of the TableViewController when a row is selected:
// TableViewController
override func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!){
var storyboard = UIStoryboard(name: "Main", bundle: nil)
var details = storyboard.instantiateViewControllerWithIdentifier("ViewController") as ViewController
var keyString = bookSectionKeys[indexPath.section]
var bookValues = book.booksLetters[keyString]!
var selectedBookString = bookValues[indexPath.row]
var selectedBookValues = book.bookDictionary[selectedBookString]!
details.BookNameString = selectedBookString
}
I was able to solve this problem a few weeks ago and I want to share the solution with you :)
I solve it using protocols.
OK Here what I did in details:
First I created a protocol in the view that I want it to display inside the popover and I named the protocol "DismissPopoverDelegate"
protocol DismissPopoverDelegate{
func didSelectBook(SelectedBook:String)
}
Then I declared a variable of type DismissPopoverDelegate and name it "delegate"
var delegate: DismissPopoverDelegate?
Then in the didSelectRowAtIndexMethod:
override func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!){
var keyString = bookSectionKeys[indexPath.section]
var bookValues = book.booksLetters[keyString]!
var selectedBookString = bookValues[indexPath.row]
delegate?.didSelectBook(selectedBookString)
}
After that inside the View that contains the popover (View Controller), I set the delegate of the view:
class ViewController: UIViewController, DismissPopOverDelegate, UIPopoverControllerDelegate{
Then to make the view confirm to the protocol DismissPopOverDelegate, I implement the method "didSelectBook" Inside the view:
func didSelectBook(SelectedBook:String){
popoverController!.dismissPopoverAnimated(true) // This is Optional
bookName.text = SelectedBook // Make the label text equal to the selected book From the table
}
Finally, I set the delegate to the tableView to View Controller
tableView.delegate = self
That's it :)
Here is the full code of the viewController that contains the popover
import UIKit
class ViewController: UIViewController, DismissPopOverDelegate, UIPopoverControllerDelegate{
#IBOutlet var booksbarButton : UIBarButtonItem
#IBOutlet var bookName : UILabel
var popoverController : UIPopoverController? = nil
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#IBAction func showTableView(sender : UIBarButtonItem) {
var tableView:TableViewController = TableViewController(style: UITableViewStyle.Plain)
tableView.delegate = self
var popoverContent:UINavigationController = UINavigationController(rootViewController: tableView)
self.popoverController = UIPopoverController(contentViewController: popoverContent)
popoverController!.delegate = self
self.popoverController!.presentPopoverFromBarButtonItem(booksbarButton, permittedArrowDirections: UIPopoverArrowDirection.Any, animated: true)
}
func didSelectBook(SelectedBook:String){
popoverController!.dismissPopoverAnimated(true)
bookName.text = SelectedBook
}
}

Resources