Xcode Swift MacOs - Hide/Show windows without a StoryBoard and without ViewController - swift

I'm making an App on my Apple macOS computer by using Swift 3
Close a window is eazy [in this way] from my main window called w by clicking button and calling the function closeotherw()
#IBOutlet var w: NSWindow!
#IBOutlet var otherw: NSWindow!
#IBOutlet var otherw: NSPanel!
#IBAction func closeotherw(_ sender: AnyObject) {
otherw.close()
}
But how to reopen-it [otherwin]?
I also tried it in all ways, also like w.isHidden = true but with no results.
I don't have a StoryBoard and I also don't have a ViewController.
I'm doing all from AppDelegate.

Method is:
otherw.orderFront(self)
Also there is:
makeKeyAndOrderFront to show it again.
You can use otherw.orderOut(self) instead otherw.close()
tnks to #Willeke
reference:
How to hide the window
Good learning!

Related

Unrecognized selector sent to instance for unhiding button

import UIKit
class ViewController: UIViewController {
#IBOutlet var continueLabel: UILabel!
#IBOutlet var yesButton: UIButton!
#IBOutlet var noButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
continueLabel.isHidden=true
yesButton.isHidden=true
noButton.isHidden=true // Do any additional setup after loading the view.
}
#IBAction func continueButton(_sender: UIButton) {
continueLabel.isHidden=false
yesButton.isHidden=false
noButton.isHidden=false
}
}
I'm a bit new to IOS development and was practicing how to hide/unhide a button. On the view controller, I can get the button hidden but when I press the button to unhide - The following error is being thrown reason: '-[WelcomeApp.ViewController ContinueButton:]: unrecognized selector sent to instance 0x12b2061d0.
It was basically a button which displayed two options - Yes or No. The Yes button is linked to the next view controller modally.
Function names, as variables, are case sensitive. You seem to have linked to ContinueButton() function, and then to have renamed it to continueButton(). Remove the link and recreate it, and then it should work.
Check the connection inspector as shown in the pic:
You can see a yellow warning, you have to remove this connection first and then again make the connection.

Swift Access Objects In View Controller From Window Controller

I'm just getting into development on mac os and I made a simple app for the touch bar that allows you to change the color (with a nscolorpicker) of a label that is also on the touch bar.
Now I would like to get the same effect on the actual window like so: I change the color using the picker on the touch bar and the color of the colorwell in the window changes as well.
This is the code that I currently have for the touch bar actions:
import Cocoa
#available(OSX 10.12.2, *)
class MainWindowController: NSWindowController {
#IBOutlet weak var cptHello: NSColorPickerTouchBarItem!
#IBOutlet var lblHello: NSTextField!
override func windowDidLoad() {
super.windowDidLoad()
// Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
cptHello.color = NSColor.white
setCol()
}
func setCol(){
lblHello.textColor = cptHello.color
}
#IBAction func colorPicked(_ sender: Any) {
setCol()
}
}
This piece of code resides in MainWindowController.swift which is paired with the window controller.
In the view controller, I have a single NSColorWell that I would like to change the color for inside the function "setCol()". I created an outlet in the view controller for it like so:
#IBOutlet var cwHello: NSColorWell!
So ideally what I want to achieve is something like this:
func setCol(){
lblHello.textColor = cptHello.color
ViewController.cwHello.color = cptHello.color
}
Can this be done at all?

How do you reference the view's window in Swift 3.x using Storyboards/Cocoa

with all the changes in Xcode and Swift, I can't figure out how to address the view's window in a stotyboard-driven project in the way I'm doing it in projects using XIBs. New to macOS programming so apologies in advance if this is basic stuff:
When using a storyboard, how do I change the view's window state using for instance:
window.titleVisibility = .hidden
window.setContentSize(size)
In an xib-driven project, I'm using
#IBOutlet weak var window: NSWindow!
but this doesn't seem to work the same way with storyboards. How do I do the same tihing using storyboards? Any help appreciated!
You can get a reference of your view window accessing its window property. Note that it can not be done inside view did load but you can create a window property for your view controller using a lazy initializer:
lazy var window: NSWindow! = self.view.window
And you can do your window customization inside the method viewWillAppear:
import Cocoa
class ViewController: NSViewController {
lazy var window: NSWindow! = self.view.window
override func viewWillAppear() {
super.viewWillAppear()
window.titleVisibility = .hidden
}
}
This seems to work:
if let window = NSApplication.shared().mainWindow {
window.titleVisibility = .hidden
}
Is this an ok way to do it?

Why would the action not be able to connect to target class NSViewController?

I'm trying to learn Swift, but I seem to have gotten stuck at this (admittedly, probably very simple) problem - the error as follows:
Could not connect action, target class NSViewController does not respond to -(encbutton/decbutton)
Here is my code. I'm designing my interface in the Storyboard and connecting it to the code through #IB(Outlet/Action).
// ViewController.swift
import Cocoa
import Foundation
class TabViewController: NSTabViewController {
// This has been changed from NSViewController to NSTabViewController as I have replaced the initial single-view with a two-tab-view.
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override var representedObject: AnyObject? {
didSet {
// Update the view, if already loaded.
}
}
}
public class EncViewController: NSViewController {
// This is for the first tab, encrypt
#IBOutlet var encdirfield: NSTextField!
#IBOutlet var encpassfield: NSSecureTextField!
#IBOutlet var enclogfield: NSTextField!
#IBOutlet var encbutton: NSButton!
#IBAction func startenc(sender: NSButton) { // here's the problem. the function isn't triggered when the button is pressed
// get values
encdir = encdirfield.stringValue
encpass = encpassfield.stringValue
tarcrypt.enc();
// this is an function that leads to an NSTask that runs a binary I wrote (not related).
// definitely not the cause of the problem because running it independently works fine
}
}
public class DecViewController: NSViewController {
// and this is for the second tab, decrypt
#IBOutlet var decdirfield: NSTextField!
#IBOutlet var decpassfield: NSSecureTextField!
#IBOutlet var declogfield: NSTextField!
#IBOutlet var decbutton: NSButton!
#IBAction func startdec(sender: NSButton) { // here's the same problem, again. the function isn't triggered when the button is pressed
// get values
encdir = encdirfield.stringValue
encpass = encpassfield.stringValue
tarcrypt.dec();
// this is an function that leads to an NSTask that runs a binary I wrote (not related).
// definitely not the cause of the problem because running it independently works fine
}
}
For some reason, upon drawing the scene along with the NSButton, the error message as seen above is generated. What is causing the error, and how do I fix it?
I've figured it out! For anyone else who runs into this problem, here's how to fix it:
It turns out there is a little dropdown under "Custom Class" titled "Module", which is, by default, set to none. Set it to tarcrypt (or whichever available option suits you) and that should fix the errors.
Thanks for all the help!
It sounds as if you connected your UI element to the File's Owner object, which is an instance of NSApplication.
If you haven't done so already, you want to drag a NSObject out of the Object Library palette in Xcode 4 to the margin to the left of your layout. Once you've done that, and have selected it, choose the identity inspector and, in the Class field, enter "WindowController"
Swift 5 and Xcode 13.3
Recently I had the same bug. I solved it by reassigning the viewcontroller class name to the class in my nameclass.swift file and activating the MODULE entry with my project name (following the dropdown menu).

Tooltip doesn't show up again

I have a Mac app that exclusively live on the menu bar. It has a progress bar and a label. The label shows the percentage of the progress of the task that's being carried out. I want to show more info when the user hovers the mouse pointer over the progress indicator.
When I set the tooltip initially and hover over, it displays without an issue.
But if I head over somewhere and open the menu app again and hover over again, the tooltip doesn't come up. I can't figure out why. Here's my code.
ProgressMenuController.swift
import Cocoa
class ProgressMenuController: NSObject {
#IBOutlet weak var menu: NSMenu!
#IBOutlet weak var progressView: ProgressView!
let menuItem = NSStatusBar.systemStatusBar().statusItemWithLength(NSVariableStatusItemLength)
var progressMenuItem: NSMenuItem!
override func awakeFromNib() {
menuItem.menu = menu
menuItem.image = NSImage(named: "icon")
progressMenuItem = menu.itemWithTitle("Progress")
progressMenuItem.view = progressView
progressView.update(42)
}
#IBAction func quitClicked(sender: NSMenuItem) {
NSApplication.sharedApplication().terminate(self)
}
}
ProgressView.swift
import Cocoa
class ProgressView: NSView {
#IBOutlet weak var progressIndicator: NSProgressIndicator!
#IBOutlet weak var progressPercentageLabel: NSTextField!
func update(value: Double) {
dispatch_async(dispatch_get_main_queue()) {
self.progressIndicator.doubleValue = value
self.progressIndicator.toolTip = "3 out of 5 files has been copied"
self.progressPercentageLabel.stringValue = "\(value)%"
}
}
}
This is a demo app similar to my actual app. So the update() function is called only once and the values are hardcoded. But in my actual app, the progress is tracked periodically and the update() function gets called with it to update the values. The label's percentage value and the progress indicator's value get updated without a problem. The issue is only with the tooltip.
Is this expected behavior or am I missing something?
I ran into the same problem, and realized the issue was that only the currently focused window will display tool-tips, but after my app lost focus, it would never get it back. Focus usually transfers automatically when the user clicks on your window, but it isn't automatic for menu bar apps. Using NSApp.activate, you can regain focus onto your app:
override func viewWillAppear() {
super.viewWillAppear()
NSApp.activate(ignoringOtherApps: true)
}
sanche's answer worked for me as well, but I ended up moving the tool tips to my NSMenuItems instead so I wouldn't have to steal focus from the foreground app. NSMenuItem's tool tips seem to be handled as a special case so the app doesn't need to be focused.
This solution would make the tool tip apply to everything in the menu item and appear next to the menu rather than over it, but it looks like that might not be a problem in your case.