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

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

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.

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

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!

EXC_BAD_INSTRUCTION error

I know that there are a lot of questions about this error, but I haven't found solution for my problem, even if I read most of them. In view controller I'm trying to make my text view displaying top of text, instead of bottom of it. When there is only one textView, then everything works perfectly, but when I try do it with two of the, , then I get EXC_BAD_INSTRUCTION error.
import UIKit
import Social
class ViewController: UIViewController {
#IBOutlet weak var textViewA: UITextView!
#IBOutlet weak var textViewB: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
textViewA.setContentOffset(CGPointZero, animated: false)
textViewB.setContentOffset(CGPointZero, animated: false)
}
If your error is like this
Then it is because you have not hooked up your outlets, to do this go into the storyboard / nib and hook it up like so:
Make sure they are valid by seeing the circles become solid:
This code works for me. I tested it on my own. This is mostly an outlet error, if they aren't connected correctly. It could also be that you have removed an outlet from your code and still have it connected inside your storyboard.

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.

'[UILabel]' does not have a member named 'text'

After I upgrade to Xcode 6.3, it is failed to assign the String into the UILabel. I got the Swift compiler error message "'[UILabel]' does not have a member named 'text'" on UILabel textLabel. Any idea to fix it?
import UIKit
class ViewController: UIViewController {
#IBOutlet var nameTxt: [UITextField]!
#IBOutlet var textLabel: [UILabel]!
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 changeLabel(sender: UIButton) {
self.textLabel?.text = "Success"
}
}
When we are hooking up labels (or anything else) from the storyboard to our source code, we will get a pop-up menu that looks something like this:
When you click "Connect" here (all I did after getting the pop-up is type "textLabel", everything else is default), it will produce the following line of code:
#IBOutlet weak var textLabel: UILabel!
However, "Outlet" is not the only option for connecting our objects from interface builder to source code.
If we change the "Connection" drop down to select "Outlet Collection", like so:
Then the line of code generated will match exactly the line of code in your question:
#IBOutlet var textLabel: [UILabel]!
We've created an array of labels. This is useful in some cases, but perhaps not what we actually want here.
In order to fix this, we must first be sure to unhook our original connection (otherwise, we'll have runtime exceptions).
So, if you go back to Interface Builder and right click on the label in question, you'll receive a menu that looks like this:
Notice how the label is linked to a "Referencing Outlet Collection", but not a "Referencing Outlet"? This is what we need to fix. So, click the X for that connection to unlink it. Now we can go to the source code and delete the #IBOutlet that was generated.
Now, rehook your label up as a regular "Outlet" and not an "Outlet Collection", and your changeLabel method will work perfectly fine as-is.
When your label is correctly hooked up as an "Outlet" rather than an "Outlet Collection", your interface builder right click menu will look like this:
(Notice the difference between this one and the previous image.)