could not connect to action "Button" in cocoa? - objective-c

I am new in cocoa application development. I am trying to create model based application in cocoa.
I created two windows in cocoa application say mainMenu.xib and windows2.xib. The mainMenu.xib is created while project creation and windows2.xib is manually created. Now I inserted a button on mainMenu.xib say (button1) and when clicked on button then window2.xib poped up but when click on button of second windows it is generated a error. the code is follwoing
AppDelegate.h
#interface AppDelegate : NSObject <NSApplicationDelegate>
And AppDelegate.mm
#import "AppDelegate.h"
#implementation AppDelegate
NSWindowController *AdvSettingController;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Insert code here to initialize your application
}
- (IBAction)AdvSettingBtn:(id)sender {
AdvSettingController= [[NSWindowController alloc] initWithWindowNibName:#"window2"];
[NSApp runModalForWindow:AdvSettingController.window];
[NSApp endSheet:AdvSettingController.window];
[AdvSettingController.window orderOut:self];
}
- (IBAction)OkBtn:(id)sender {
[NSApp terminate:self];
}
- (IBAction)CancelBtn:(id)sender {
[NSApp terminate:self];
}
Now, windows2.h file for second windows(windows2.xib)
#import <Cocoa/Cocoa.h>
#interface windows2 : NSWindowController
#end
and windows2.mm
#import "windows2.h"
#interface windows2 ()
#end
#implementation windows2
- (id)initWithWindow:(NSWindow *)window
{
self = [super initWithWindowNibName:#"windows2"];
if (self) {
// Initialization code here.
}
return self;
}
- (void)windowDidLoad
{
[super windowDidLoad];
// Implement this method to handle any initialization after your window controller's window has been loaded from
}
- (IBAction)CancelBtn:(id)sender {
[self.window close];
} **//Error is generating at run time when clicked on button of second dialog**

You are trying to connect the CancelButton method, but the instance method is named CancelBtn.

Related

awakeFromNib gets called twice and outlets inside viewcontroller are not set

I am trying to build a menubar application for OSX.
I have a AppDelegate, a Storyboard and a ViewController.
The storyboard contains a application scene with the AppDelegate. The AppDelegate sets up the whole view hierarchy. Inside the AppDelegate I define a NSPopover with a ContentViewController(My ViewController). In order to set the ContentViewController I load the ViewController from the storyboard with the following code:
NSStoryboard*board=[NSStoryboard storyboardWithName:#"Main" bundle:nil];
_ruleView.contentViewController=[board instantiateControllerWithIdentifier:#"egm"];
When I use the debugger to examine the awakeFromNib method the outlets inside the ViewController are not set why?
The next problem is when the NSStatusItem is clicked it shows the NSPopover and the NSPopover calls the awakeFromNib inside my ViewController again and then my application crashes.
Here is the code of the AppDelegate:
#import "AppDelegate.h"
#import "ViewController.h"
#interface AppDelegate()
{
NSStatusItem*_statusItem;
NSPopover*_ruleView;
}
-(void)statusItemButtonPressed:(id)sender;
-(void)openPopupWindow;
-(void)closePopupWindow;
#end
#implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
}
-(id)init
{
self=[super init];
if(self)
{
_ruleView=[[NSPopover alloc] init];
NSStoryboard*board=[NSStoryboard storyboardWithName:#"Main" bundle:nil];
_ruleView.contentViewController=[board instantiateControllerWithIdentifier:#"egm"];
_statusItem=[[NSStatusBar systemStatusBar] statusItemWithLength:24];
_statusItem.button.title=#"EG";
_statusItem.button.action=#selector(statusItemButtonPressed:);
}
return self;
}
-(void)statusItemButtonPressed:(id)sender
{
if(!_ruleView.shown)
{
[self openPopupWindow];
}
else
{
[self closePopupWindow];
}
}
-(void)openPopupWindow{
[_ruleView showRelativeToRect:NSZeroRect ofView:_statusItem.button preferredEdge:NSMinYEdge];
}
-(void)closePopupWindow{
[_ruleView close];
}
- (void)applicationWillTerminate:(NSNotification *)aNotification {
// Insert code here to tear down your application
}
I figured out that awakeFromNib can be called several times while unarchiving the view hierarchy from a nib. A better alternative is viewDidLoad which ensures that the whole view hierarchy is loaded and ready.

NSTabView blocking file-drop events active on underlying Window.

I have successfully implemented a file-drop functionality in my app. The Application window has a few NSTabView objects where dropping on them does not work. Anywhere else in the window the file-drop works fine.
I have tried to make the app delegate a delegate for the NSTabView, but this did not help.
Anyone have a setup for the NSTabView not to filter out the drop-actions so the whole window can be transparent to the file-drop actions ?
For a more generic solution than olekeh's I made it IB friendly so you can hook it up to any object that complies with the NSDraggingDestination protocol.
#import <Cocoa/Cocoa.h>
#interface DropFilesView : NSView
#property (nullable, assign) IBOutlet id<NSDraggingDestination> dropDelegate;
#end
#implementation DropFilesView
- (void)drawRect:(NSRect)dirtyRect {
[super drawRect:dirtyRect];
}
-(void) awakeFromNib {
[self registerForDraggedTypes:
[NSArray arrayWithObjects:NSFilenamesPboardType,
(NSString *)kPasteboardTypeFileURLPromise,kUTTypeData, NSURLPboardType, nil]]; //kUTTypeData
[super awakeFromNib];
}
-(NSDragOperation)draggingEntered:(id<NSDraggingInfo>)sender{
return [self.dropDelegate draggingEntered:sender];
}
- (BOOL)performDragOperation:(id < NSDraggingInfo >)sender {
return [self.dropDelegate performDragOperation:sender];
}
#end
I found the solution to this !! - I am posting it here for others who might need.
The NSTabView object has for each of its tabs an NSTabViwItem.
Under each of those, there is a regular NSView - that I subclassed with the following code: - The code assumes that you already have "draggingEntered" and "performDragOperation" in your AppDelegate as this class just forwards these messages to the app delegate. You will also need to put the declarations for those methods in you AppDelegate.h
// DropFilesView.h
#import <Cocoa/Cocoa.h>
#import "AppDelegate.h"
#interface DropFilesView : NSView
#end
and the implementation:
// DropFilesView.m
#import "DropFilesView.h"
#implementation DropFilesView
- (void)drawRect:(NSRect)dirtyRect {
[super drawRect:dirtyRect];
}
-(void) awakeFromNib {
[self registerForDraggedTypes:
[NSArray arrayWithObjects:NSFilenamesPboardType,
(NSString *)kPasteboardTypeFileURLPromise,kUTTypeData, NSURLPboardType, nil]]; //kUTTypeData
[super awakeFromNib];
}
-(NSDragOperation)draggingEntered:(id<NSDraggingInfo>)sender
{
AppDelegate* del = [AppDelegate sharedAppDelegate];
return [del draggingEntered:sender];
}
- (BOOL)performDragOperation:(id < NSDraggingInfo >)sender {
AppDelegate* del = [AppDelegate sharedAppDelegate];
return [del performDragOperation:sender];
}
#end
In Interfacebuilder, I set the new class for all the NSView objects covering areas where drop does not work, to this new one.
A similar approach can be used for NSImageView and the WebView classes. However, for the last one, do not use [super awakeFromNib] to prevent the default drag-and drop handling for the web view object.

NSPanel not showing.

My approach to this may be all wrong so I appreciate your patience.
I have a button in my main XIB file linked to this method in my document.m file:
- (IBAction)showTagModal:(id)sender {
if (!_FileTagWindowController){
_FileTagWindowController = [[FileTagWindowController alloc]init];
}
[_FileTagWindowController showWindow:self];
}
_FileTagWindowController is declared as a property in document.h and using breakpoints when the method is called, as far as I can tell is initializing properly, however _windowNibName and _window remains nil.
FileTagWindowController.h looks like this.
#import <Cocoa/Cocoa.h>
#interface FileTagWindowController : NSWindowController{
}
#property (strong) IBOutlet NSArrayController *tagsArray;
- (IBAction)saveContext:(id)sender;
#end
FileTagWindowController.m looks like this:
#import "FileTagWindowController.h"
#interface FileTagWindowController ()
#end
#implementation FileTagWindowController
- (id)initWithWindow:(NSWindow *)window
{
self = [super initWithWindow:window];
if (self) {
// Initialization code here.
}
return self;
}
- (void)windowDidLoad
{
[super windowDidLoad];
NSLog(#"Window Did Load!");
// Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
}
- (IBAction)saveContext:(id)sender {
}
#end
in my FileTagWindowController.xib I have File Owner set to FileTagWindowController as the custom class. I have the File Owner's "window" outlet linked to the window (NSPanel). That's all that should be required correct? The NSLOG statement in WindowDidLoad never gets called. I tried using [super initWithWindowNibName] in FileTagWindowController.m but that crashes not only the app, but Xcode as well with an endless initialization loop. Am I missing something obvious here?
Thanks all so much.
Try something like the following.
// document.h
#import "FileTagWindowController.h"
#property (strong) filetagWindowController *FileTagWindowController;
// document.m
#synthesize filetagWindowController;
- (IBAction)showTagModal:(id)sender {
if (self.filetagWindowController == nil) {
self.filetagWindowController = [[FileTagWindowController alloc] initWithWindowNibName:#"FileTagWindowController"];
}
[filetagWindowController showWindow:self];
[[filetagWindowController window] setReleasedWhenClosed:NO];
[NSApp runModalForWindow:filetagWindowController.window];
filetagWindowController = nil;
}
You may also want to call NSWindowWillCloseNotification to observe its state and see if filetagWindowController is closed.

Second Window Creation Objective-C Cocoa

I was wondering if it is possible to open a second window with like a button. I have no clue how to do this, please help.
First set up an IBAction to get called when the user clicks the button.
- (IBAction)buttonClicked:(id)sender {
}
In Interface Builder, control-drag from the NSButton object you want to fire that action to the method implementation.
Now, to create a second window, you'll probably want to create a SecondWindowController class to manage it. Declare an IBOutlet to the NSWindow and hook it up in Interface Builder, just like you did for the IBAction (by control-dragging to the IBOutlet declaration).
In the initializer, load the nib file that contains the window you're presenting.
- (id)init {
if (self = [super init]) {
[NSBundle loadNibNamed:#"DubBouncerConversionProgressWindow" owner:self];
}
return self;
}
Then, define a method to present the window by calling orderFront: on it.
- (void)displayWindow {
if (![progressWindow isVisible]) {
[progressWindow setIsVisible:YES];
[progressWindow orderFront:nil];
}
}
Now, when the user clicks the button you can call -displayWindow on an instance of SecondViewController.
- (IBAction)buttonClicked:(id)sender {
[mySecondViewController displayWindow];
}
Here's a full picture of what's going on:
FirstViewController.h
#interface FirstViewController : NSObject {
SecondViewController *mySecondViewController;
}
- (IBAction)buttonClicked:(id)sender;
#end
FirstViewController.m
#implementation FirstViewController
- (IBAction)buttonClicked:(id)sender {
if (!mySecondViewController) {
// If the second view controller doesn't exist yet, make it!
mySecondViewController = [[MySecondViewController alloc] init];
}
[mySecondViewController displayWindow];
}
#end
SecondViewController.h
#interface SecondViewController : NSObject {
IBOutlet NSWindow *progressWindow;
}
- (void)displayWindow;
#end
SecondViewController.m
#implementation SecondViewController
- (id)init {
if (self = [super init]) {
[NSBundle loadNibNamed:#"DubBouncerConversionProgressWindow" owner:self];
}
return self;
}
- (void)displayWindow {
if (![progressWindow isVisible]) {
[progressWindow setIsVisible:YES];
[progressWindow orderFront:nil];
}
}
#end
Connect the button to the NSWindow's orderFont: action. I haven't got Xcode 4, so I can't tell you how to do it in there, but for Xcode 3, open the xib in Interface Builder. While holding the control key, click and drag a line from the button to another window in the nib (drag over the title bar if the window is opened up, otherwise drag it onto the icon in the xib project window). In the menu that pops up, choose "orderFront:" or "makeKeyAndOrderFront:" (depending on the required behaviour).
If the window is in another nib, you'll need to use an approach like Stephen's.

Show new window from status menu [duplicate]

OK, what am I doing wrong?
1. Created cocoa app and appDelegate named: window2AppDelegate
2. window2AppDelegate.h
#import "PrefWindowController.h"
#interface window2AppDelegate : NSObject <NSApplicationDelegate> {
NSWindow *window;
PrefWindowController * ctrl;
}
#property (assign) IBOutlet NSWindow *window;
- (IBAction) buttonClick:(id)sender;
- (IBAction) buttonCloseClick:(id)sender;
#end
3. in xib editor, window connected to window controller - set to appdelegate, buttonclick actions to buttons
4, created
#import <Cocoa/Cocoa.h>
#interface PrefWindowController : NSWindowController {
#private
}
#end
#import "PrefWindowController.h"
#implementation PrefWindowController
- (id)init {
self = [super initWithWindowNibName: #"PrefWindow"];
return self;
}
- (void)dealloc {
// Clean-up code here.
[super dealloc];
}
- (void)windowDidLoad {
[super windowDidLoad];
// Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
}
#end
5. created new xib file named PrefWindow window IBOutlet connected to window from its controller (also controller set to PrefWindowController) Option "Visible At Launch" UNCHECKED! i want to see this window on buttonclick.
6. implemented window2AppDelegate
#import "window2AppDelegate.h"
#implementation window2AppDelegate
#synthesize window;
- (id) init {
if ((self = [super init])) {
ctrl = [[PrefWindowController alloc] init];
if ([ctrl window] == nil)
NSLog(#"Seems the window is nil!\n");
}
return self;
}
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender {
return YES;
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
// Insert code here to initialize your application
}
- (IBAction) buttonClick:(id)sender {
// [[ctrl window] makeKeyAndOrderFront:self]; this doesn't work too :(
NSLog(#"it is here");
[ctrl showWindow:sender];
}
- (IBAction) buttonCloseClick:(id)sender {
[window close];
}
#end
7. After I build and run app: closebutton closes the app but buttonclick - won't show me PrefWindow!? Why and what am i doing wrong? Don't dell me that to show other window in cocoa objective-c is more difficult than in "stupid" Java or C#?
Finally i've managed the problem! In the nib editor for PrefWindow I had to do: Set File's owner class to: NSWindowController then connect window IBOutlet from File's owner to my (preferneces) window. After 6 days of unsuccessful attempts, google works.
Anyway, thanks for all your responses and time!
I'd suggest you move the creation of the PrefWindowController to applicationDidFinishLaunching:
I am not sure the application delegate's init method is called. Probably only initWithCoder: gets called when unarchiving the object from the NIB.
- (id) init {
if ((self = [super init])) {
ctrl = [[PrefWindowController alloc] init];
if ([ctrl window] == nil)
NSLog(#"Seems the window is nil!\n");
}
return self;
}
init is way too early in the scheme of things to be trying to test IBOutlets. They will still be nil yet. Not until later on in the object creation process will the nib outlets be "hooked up". The standard method where you can know that everything in the nib file has been hooked up is:
- (void)awakeFromNib {
}
At that point, all of your IBOutlets should be valid (provided they're not purposely referencing an object in a separate, yet-unloaded nib).
If PrefWindowController is a class that will only be used after the user chooses Preferences from the app menu, I would have to disagree with the others and say that I would not create the instance of the PrefsWindowController at all during the initial load. (Your main controller should be able to function independently from the prefs window). If you have a method that is meant to load the preferences window, then when that method is called, you should check to see if the PrefsWindowController instance is nil, and if it is, create it, then proceed to show the prefs window.