How to detect a click from an NSToolbarItem inside an NSWindowController? - swift

I have a toolbar on my macOS app, developed in Swift. The toolbarItem is dragable onto the NSWindowController, and I can setup an IABAction function, I just have a print in the function at the moment. And when I click on the button nothing happen the click does not seem to be recognised as an action ?
I had a few more line of code in the function but deleted it and now have just the print("test") line.
#IBAction func exportCsvClicked(_ sender: NSToolbarItem) {
print("test") }
No output observed, so I'd love to get "test" in the console when I click on this button.
Here is a list of the connections associated with the toolbarItem.

I found a way to get around the fact that the IBAction from an NSToolbarItem does not recognise the click on this item:
1/I made a customSegue from the item to the main window controller (it can go anywhere)
2/The prepare for segue function posts a notification to the notification saying that the item has been clicked.
3/The main view controller observes the notification and presents, either has a popup or a sheet (I got two buttons), the view that I have setup in the storyboard (referencing with the storyboardID). I found that you need to pass on all the necessary variable to setup the view from the main view Controller, and that there was issue of code in the viewDidLoad function of the sheet/popup view not running, I am suspecting that they might be different instances.

Related

Segue from SKScene and back again cause game to "freeze"

I'm developing a SpriteKit game with two different scenes (MainMenu.sks and Settings.sks). I also have a UIViewController.
From the MainMenu the user can tap "Settings" which causes the app to load the Settings.sks scene and present it.
It's done using this code:
// Move to Settings.sks
let transition = SKTransition.flipVertical(withDuration: 1.0)
let loadScene = SettingsScene(fileNamed: "SettingsScene")
loadScene?.scaleMode = self.scaleMode
self.view?.presentScene(loadScene!, transition: transition)
From the Settings.sks scene the user can tap on the SKLabelNode "Change username" which causes the app to load the UIViewController by performing a segue.
The UIViewController contains a UITextField and a UIButton. The UIButton takes the user back to MainMenu.sks.
However, when I'm doing so the it's like a new scene of MainMenu is placed upon the other causing the app to sort of "freeze" and not responding to any touch gestures. I can see from the nodeCount that the nodes are doubled.
A workaround is loading the UIViewController directly from the MainMenu.sks (also via a segue). By doing so, the app works just fine.
I'm suspecting the problem to be the way I load Settings.sks.
What am I missing? Maybe unloading the entire SKView before exiting?
Performing a segue will present a new view on top of the stack. By using a segue to return to the main menu, the app will create a new main menu on top of the UIViewController. I can't say for certain why your app freezes. But I would guess that there are some properties or functions that don't work properly when a new main menu is created and presented from your UIViewController.
I recommend unwinding the segue used to reach the UIViewController instead. This way you can return to the previous view and conserve memory.
You'll need to write an IBAction in your destination view, the main menu in this case:
#IBAction func unwindToMainMenu(segue: UIStoryboardSegue) {
}
Then ctrl-drag from your button in the UIViewController to the exit icon in storyboard. You should see an option to use the IBAction unwindToMainMenu that you just wrote. This will create an unwind segue.
A complete guide to unwind segues and multiple examples can be found in this answer: What are Unwind segues for and how do you use them?

Updating UIView by pressing button

I have little problem with my app. On main ViewController i have embbed Container View with objective-C chart.
I have 2 buttons and always when i press it i need update this UIView. Everything like setNeedsDisplay() not working.
But when i go to another ViewController and going back, my chart is updated.
Here is my main controller:
By buttons i go to previous year and data not updated.
But going to Another ViewController and:
Booom data updated. Im trying methods like: IBAction when button is pressed call function setNeedsDisplay() for self or view.
Thanks for your time! PS: Its not table, its CONTAINER VIEW.
Here is my project tree:
TREE
and i have container view to embbed this:
view
So i just need refresh UIViewController when i press button. Doesnt have any conection with objective-c to swift code (just one string array).

Open URL on Menu Item Click

I need to Open a URL when the user clicks on a Menu Item.
Currently I'm using the following code
url = URL(string: "https://www.example.com/test")
NSWorkspace.shared().open(url)
This works fine from a Button.But I cannot connect a Segue from the Menu Item to the view controller inorder to setup an IOAction,so that I can write the necessary code.
How can I solve this problem? Please advice.
Segues are for opening new views or windows from your app. You should implement your function as ordinary #IBAction in your view controller or app delegate, and connect action under Sent Actions in the Connections Inspector with the First Responder in the storyboard scene. You will find your action method there. Cocoa touch will automatically enable or disable the menu item weather the view controller is in the responder chain. If you implement the action method in the app delegate the menu item should always be enabled, because the delegate is always in the responder chain.
#IBAction func openURL(_ sender: AnyObject) {
let url = URL(string: "https://www.example.com/test")
NSWorkspace.shared().open(url)
}
Implement the method as IBAction in the view controller.
Connect the NSMenuItem to First Responder (red cube) of the Application Scene and select the method.
If there are multiple implementations of the method the framework executes the first in the responder chain.

Update text field values in multiple tabs with single button

I have 6 tabs in my application.
Each tab has a text field.
There is one button in the sixth tab, which when pressed, should reset the text fields in all the other 5 tabs to blank.
I am unable to figure out any direction in which I should look.
I am pretty new to Xcode, so please pardon my ignorance on this topic.
One thing I have tried so far is to set global variable.
When I press the button, I update the global variable to ""
But then I go to the other tabs, the value has not been updated.
My understanding is that I an not writing the code in the right place.
Currently, I have written this code in viewDidLoad function of each tab's viewController class:
override func viewDidLoad() {
super.viewDidLoad()
telephone.text = ViewLine.GlobalVariable.phone1
timerData.text = ViewLine.GlobalVariable.concept1
}
phone1 and concept1 are my global variables.
Would anyone be able to suggest where should I write this code? or is there a better way to do this?
Thanks
Write code in viewWillAppear
override func viewWillAppear() {
super.viewWillAppear()
telephone.text = ViewLine.GlobalVariable.phone1
timerData.text = ViewLine.GlobalVariable.concept1
}
I think that what you want is the first 5 view controllers to react to a tap on a button in the 6th view controller.
In that case - don't use global variables.
Use notifications:
When the button did tap, send a notification. The first 5 view controllers should subscribe to this notification channel. When each of the first 5 view controllers receive a notification they should change the text to "".
Here is a link on notifications:
https://www.raywenderlich.com/160653/design-patterns-ios-using-swift-part-22

Button ignores action when segued to a previous viewcontroller

So here is my current issue.
I want to unwind to a previous viewcontroller lets call it viewcontroller1.
This works fine, except that the button action
that is hooked up with the segue, also has a lot of other code written in it. However, when pressing the button xcode ignores the code thats already written.
So this is my question how do I make the button perform the written code and then engage the segue??
For the unwind segue I've created an empty action in ViewController1.
#IBAction func unwindtoViewcontroller1(segue: UIStoryboardSegue){}
And hooked ViewController2 up with this segue action (using ViewController2:s exit button).
Ive also set the segue to "revealviewcontrollerpushviewcontroller"
Thanks in advance for all the help I can get I am really stuck.
Best regards Albin
You should be able to do it this way:
Open Assistant Editor, then control drag from the button that performs the unwind segue in ViewController 2 to create an IBAction. That's where all the code for the action you would like your button to do should go.
This action gets performed before the unwind segue function is called.
So your button will do both: action and unwind.
I have made a simple project to illustrate and printed the output to the console. The button in yellowVC performs an action before unwind.
So as you said, in the first ViewController (in my example the green one you have an IBAction for unwind segue
#IBAction func goBackToGreenVC(segue: UIStoryboardSegue) {
print("go back")
}
Then in the second ViewController (in my case the yellow one), control drag from the button to Exit to set unwind segue and then also control drag from the button to Assistant Editor for an IBAction, something like:
#IBAction func goBackToGreenVCButtonTapped(_ sender: UIButton) {
print("performing an action before unwind")
}