How to call function in NSViewController? - macos

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

Related

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")

How to get UIActivityIndicator to disappear once appearing?

I currently have my app linking to a certain URL upon opening the app, and this obviously can have a delay between opening it and the webView actually loading, so I want it to display an activity indicator whenever the webView is loading, I have the following code in my ViewController.swift:
class ViewController: UIViewController, UIWebViewDelegate {
#IBOutlet weak var webView: UIWebView!
#IBOutlet weak var activityIndicator: UIActivityIndicatorView!
override func viewDidLoad() {
super.viewDidLoad()
webView.delegate = self
let url = URL(string: "url to site")
webView.loadRequest(URLRequest(url: url!)
}
func webViewDidStartLoad(webView: UIWebView){
activityIndicator.startAnimating()
}
func webViewDidFinishLoad(webView: UIWebView){
activityIndicator.stopAnimating()
}
The activity indicator shows up from the beginning but it does not disappear once the webView loads and stays their forever.
The way you have your code organized is a bit confusing. It appears you are declaring your funcs inside the #IBAction function. If this is the case, this will not work.
Try this instead
class ViewController: UIViewController, UIWebviewDelegate {
override func viewDidLoad() {
...
webView.delegate = self
// You should add this to your Storyboard, above the webview instead of here in the code
activityIndicator.center = self.view.center
activityIndicator.hidesWhenStopped = true
activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.gray
// I forget the actual method name - look it up
view.insertSubview(activityIndicator, above: webView)
}
#IBAction func openButton(_ sender: Any) {
let url = URL(string: "websiteURL")
webView.loadRequest(URLRequest(url: url!))
}
func webViewDidStartLoad(webView: UIWebView){
activityIndicator.startAnimating()
}
func webViewDidFinishLoad(webView: UIWebView){
activityIndicator.stopAnimating()
}
// You'll also want to add the "didFail" method
}
The issue is a syntax issue, you have to add an underscore in the functions.
override func viewDidLoad() {
super.viewDidLoad()
webView.delegate = self
let url = URL(string: "your URL")
webView.loadRequest(URLRequest(url: url!))
}
func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool{
activityIndicator.startAnimating()
return true
}
func webViewDidStartLoad(_ webView: UIWebView){
activityIndicator.startAnimating()
}
func webViewDidFinishLoad(_ webView: UIWebView){
activityIndicator.stopAnimating()
}
func webView(_ webView: UIWebView, didFailLoadWithError error: Error){
activityIndicator.stopAnimating()
}

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

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

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

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