Menu bar application actions with Objective C? - objective-c

I've recently been trying to create an application on Xcode 9.4.1 with the Objective-C programming language.
I am trying to make the application work from the menu bar rather than a full app.
However, I have only managed to make the Menu items show up and have no idea how to add actions such as a web link to the buttons.
Can anyone help with this? All I want is to add actions to the buttons using code.
P.S. I am not using storyboards.

Without providing what you've done so far it seems like you're asking for complete code, nevertheless I happen to have an old project that does it. In the app delegate you do something like this: in the barItemAction method you can do whatever you need to perform
#interface AppDelegate ()
#property NSStatusItem *barItem ;
#end
#implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
self.barItem = [NSStatusBar.systemStatusBar statusItemWithLength:NSVariableStatusItemLength];
self.barItem.button.title = #"🚀";
[self.barItem setAction:#selector(barItemAction)];
// Insert code here to initialize your application
}
-(void)barItemAction {
NSLog(#"🚀 button was clicked ");
}

Related

menuWillOpen: and menuDidClose: not invoked for NSMenuDelegate

[Edit] as Willeke helpfully points out it's menuDidClose: NOT menuWillClose:. My code actually had that part right. Correcting the post in case someone else finds this researching a similar problem.
I'm sure this is just a Cocoa newbie problem but I've wracked my brain on it for hours. I've read the NSMenu and NSMenuDelegate docs a few times trying to figure out what I'm missing but it looks straight forward.
I have a window controller for a preferences window with a toolbar and three views. The window controller is declared as NSMenuDelegate.
#interface PrefsController : NSWindowController <NSMenuDelegate, NSWindowDelegate, NSOpenSavePanelDelegate>
This issue is a NSPopUpButton on the first view. The menu associated with popupbutton works fine. I can modify, etc. the menu via the associated IBOutlet variable. It's bound to Shared User Defaults Controller for selected value and that works fine.
But the menuWillOpen: and menuDidClose: methods are not invoked when the menu is accessed.
- (void)menuWillOpen:(NSMenu *)menu {
if (menu == myPopupButton.menu) {
[self updateMenuImages:NSMakeSize(32, 32)];
}
}
- (void)menuDidClose:(NSMenu *)menu {
if (menu == myPopupButton.menu) {
[self updateMenuImages:NSMakeSize(16, 16)];
}
}
My apologies for what is almost certainly a dumb mistake on my part, but I'm stumped.
Menu delegates are not used that often, so Apple hasn't made them too easy to set up in Interface Builder. Instead, do this in awakeFromNib:
myPopupButton.menu.delegate = self;

Call a method in appDelegate from a button action connected with an nsView

Here is my problem. I have an NSTextField connected to my app delegate. Then i have a CustomView in my MainManu.xib associated with a new class i created, "myView", sublass of NSView. finally a Button that trigger an action declared in myView.h. (i drag n drop from button to the custom view and selected the action pushFromView)
This action is implemented in myView.m in this way:
-(IBAction)pushFromView:(id)sender{
[self.myApp getMeFromView];
}
myApp is an instance of AppDelegate that contain the method getMeFromView which is supposed to get the text from the textfield and log it.
#import "GTAppDelegate.h"
#implementation GTAppDelegate
#synthesize myText;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Insert code here to initialize your application
}
-(void)getMeFromView{
NSLog(#"valuefromView= %d",[myText intValue]);
}
#end
Now anytime i press the button it trigger the method but even if the textfield is filled with numbers it returns me zero. Instead if i create a button connected with an action in appDelegate it works properly.
an instance of myApp is declared in myView header and the property as well.
Im kinda rookie, so maybe I explained myself in a non proper way. I hope you can get it.
Thanks in advance for your help.
Luca
Use just [myApp getMeFromView] instead of [self.myApp getMeFromView].

How do i close instance of NSWindowController

I'm learning some obj-c and therefore i'm building a small cocoa application.
From the MainMenu.xib i have added a menu to the "Main menu" in the top. When click, this triggers a IBAction that opens an instance of a window, in this case a window for managing categories.
This category window has a NSWindowController, looks like this:
// CategoriesWindow.h
#import <Cocoa/Cocoa.h>
#interface CategoriesWindow : NSWindowController
-(IBAction)OpenCategoriesWindow:(id)sender;
#end
// CategoriesWindow.m
#import "CategoriesWindow.h"
#implementation CategoriesWindow
-(IBAction)OpenCategoriesWindow:(id)sender
{
CategoriesWindow *Categories = [[CategoriesWindow alloc] initWithWindowNibName:#"CategoriesWindow"];
[Categories showWindow:self];
}
#end
To this i have a CategoriesWindow.xib with a NSTableView that does some things, so there for i have a CategoryTableController.h and .m that handles the data for this table.
When i hit a button i want it to do a bunch of things, and then i want the window to close it self. That is, i want this window to close itself from a IBAction in the CategoryTableController.m.
How do I do this? One bad thing with this setup (followed from a tutorial somewhere...) is that I can open a lots of instances of this window by clicking the menu-button.
Any tips or ideas where to begin?
From there Reference:
[Categories close];
However there is something wrong with your implementation as you are creating an instance of the class from an instance method of the class. That doesn't look right to me. Also you aren't retaining the new instance anywhere, so it will be possibly destroyed under ARC or leaked under MRR.
I think you might want:
-(IBAction)OpenCategoriesWindow:(id)sender
{
[self showWindow:sender];
}
-(IBAction)CloseCategoriesWindow:(id)sender
{
[self close];
}
Although I can't be sure.

Implement a keyboard click sound, lost

Everyone on this site has been very helpful on my schooling of iOS programming, but I've run into a brick wall with a very simple feature. I've found Apples documentation on implementing the factory keyboard click sound upon a button touch, but what Im not getting is the "creating a sub lass of UIView" part. I have a very basic calculator that I've built, the buttons are made of standard Round Rect's that I want to make the simple click sound. So Apple says:Adopting the UIInputViewAudioFeedback Protocol
Perform the following three steps to adopt the UIInputViewAudioFeedback protocol:
In your Xcode project, create a subclass of the UIView class. In the header file, indicate that the subclass conforms to the UIInputViewAudioFeedback protocol, as follows:
#interface KeyboardAccessoryView : UIView {
}
Now I am using the standard UIViewController tied to a xib with all my buttons. Am i to: Create New File, name it as a subclass of UIView, JUST so i can implement this sound? That doesn't make sense to me, and if this is really amateur stuff I apologize, but I'm learning from many different places. Thanks in advance.
You have to set your custom input view as the inputView property of the object that is supposed to be the first responder (For example, a UITextField instance), and the inputView(your custom input view) must conform to the UIInputViewAudioFeedback protocol. And to actually play a click sound: [[UIDevice currentDevice] playinputClick].
For example:
#interface MyCalculatorDisplay : UIView
// ...
#end
#interface MyCustomKeyboard : UIView <UIInputViewAudioFeedback>
// ...
#end
// Then, somewhere in your controller:
MyCustomKeyboard *keyboard = [MyCustomKeyboard new];
MyCalculatorDisplay *display = [MyCalculatorDisplay new];
display.inputView = keyboard;

How to raise an event in Objective-C

I'm a little confused about raising an event in Objective-C,
I came from C# (.NET) environment and I would like to learn Objective-c and Cocoa programming.
So here's my question:
I have a little application with a NSTextField that I want to use to listen to an event.
What I want to do : When I double click within this control, it raise an event and pop up ex: an NSAlert that displays "Double clicked".
So how can I do that, I'am a visual person so I need some code exemple to show how it's work; Like what should I put within the .h class and within the .m class.
Thanks in advance,
Alex.
You need to read up on the Cocoa Fundamentals and the target/action mechanism. An NSControl (like its NSButton subclass) has a target to which it sends an action with itself as the sender. Not all controls support -doubleAction, but some do.
NSButton/NSButtonCell does not support a double action, so you would need to do some subclassing and override the mouse methods. NSEvent (which is passed into mouse methods) can be queried for its click count to distinguish double-clicks from singles.
Just for the record, it's usually click-and-hold that produces a context menu on OS X and this capability is announced through a down-facing arrow somewhere on the right of the button face. Few people will actually know a menu is there for double-clicking and it's hard to represent this with a symbol on the button face. Consider a click-and-hold trigger for your button's context menu.
I am not sure why you want to do this in a text field, but here is how to do it:
You need to use a subclass that overrides click behavior for double clicks. The header file would look like this:
#import <Cocoa/Cocoa.h>
#interface ClassName : NSTextField {
//Any new instance variables here
}
//Any new methods here
#end
and the implementation file would look like this:
#import "ClassName.h"
#implementation ClassName
- (void)mouseUp:(NSEvent *)event {
//You can also do this with mouseDown:, depending on when you prefer to handle the event
if([event clickCount] == 2) {
//Handle double click here
} else [super mouseUp:event]; //or pass to parent implementation
}