How to hook up NSWindowDelegate in macOS game template - objective-c

This is a "how-to" for related question:
cocoa windowDidEnterFullScreen not being called
Using the Xcode (9.1) macOS "game" template -
I would like to create a simple NSWindowDelegate using the AppDelegate class. However I can't seem to connect the given NSWindow outlet to anything.
// AppDelegate.h
#import <Cocoa/Cocoa.h>
#interface AppDelegate : NSObject <NSApplicationDelegate, NSWindowDelegate>
#property (assign) IBOutlet NSWindow *window; // won't connect
#end
I assume I'm supposed to connect to a "Window" within the storyboard. This is what happens when I try to connect - the inspector does not show up.
What am I missing here?
Note: I'm just playing around so I don't care if AppDelegate is the right place or not, I just want something to work.
EDIT 1
Using suggestion from answer, I've tried connecting the 'TestFullscreen' window to the AppDelegate object, but it still won't connect, either from the AppDelegate inspector or the property declaration in the code.

You should have a Delegate object and that is what should hook up to your window.
It looks like you are currently attempting to connect the window to itself. Also it doesn't appear you have a view for the window either, so you'll need to add that for the window content.

A workaround is to simply create non-Workspace project.
Editing the XIB allows you to connect the Window delegate outlet to the AppDelegate, after it has NSWindowDelegate protocol specified.

Related

Using CorePlot with OSX for OSX App

Some background: I'm making a Obj-C project for some numerical analysis, and want to add a graph. I found core-plot, and had no problem adding the framework and QuartzCore frameworks to my project.
My question now is how to actually utilise it - I have a project with an interface through Interface Builder (MainMenu.xib), an AppDelegate and another class used for modelling the mathematics. I have searched the internet and can only find tutorials for its use within iOS, which isn't what I'm doing - and I don't understand how to convert that to OSX.
I had assumed that I would add a custom view to the MainMenu.xib and link that to a new property using someting along the lines of
#property (assign) IBOutlet NSView *graph;
Although now that I look at it, putting a NSView object inside a NSObject interface seems silly.
Thanks in advance for your help!
Update 1: So I changed my code to
#property (assign) IBOutlet CPTGraphHostingView *graph;
And changed the property of the custom view to the same, CPTGraphHostingView. The two are now linked, and I have an outlet called "graph" to play with. The challenge is now putting a graph into that space.
Thanks again!

Why is my NSTextField not responding to setStringValue?

I have an object which is hooked up to interface builder (one of the little blue boxes down the left hand side (Xcode 4.5.2) and I have created bindings to an NSTextField as I am used to doing. I have also synthesised the text field in the main file (don't quite understand why but pretty sure this is necessary). However, when I try sending setStringValue:#"a string" to the text field, it doesn't work. Also, when I try and print the text field object to the command line it says null. From googling, I think some people have this problem when they use init instead of awakefromnib but this method in my programme is triggered when I press a button. The code is below. If any more information is needed, let me know. Thanks.
#import <Foundation/Foundation.h>
#import "CSSRuleSet.h"
#interface RuleSetViewUpdater : NSObject
#property (weak) IBOutlet NSTextField *top;
-(void)updateFields:(CSSRuleSet *)RuleSet;
#end
.
#import "RuleSetViewUpdater.h"
#implementation RuleSetViewUpdater
#synthesize top = _top;
-(void)updateFields:(CSSRuleSet *)RuleSet
{
[_top setStringValue:[RuleSet getValue:#"top"]];
NSLog(#"%#", _top);
}
#end
xib structure
Ok, so I realised what I was doing wrong. Basically, I had connected up the interface builder to the object exactly fine and it would of worked but because of the nature of my programme, I was initialising a new object to control the interface not realising that by doing that it would not have access to the interface. So basically instead I had to pass the original object. That probably does not make any sense but let me know if it needs explaining better.
First of all you need a connection from your sourcefile to the object in the XIB file. You have an outlet defined, but it's not sure that it's actually connected. Right-click on the object in the XIB file and make sure the outlet is connected.
Your NSLog statement ( NSLog(#"%#", _top); ) logs the NSTextField object itself. The fact that it logs "(null)", means that the outlet is not (yet) connected. When your XIB file gets loaded, the outlets are not immediately connected. awakeFromNib() gets called on all the objects in the XIB file when the file is loaded. After this, you should be able to access the objects by using the outlets.

Binding in Interface Builder

i am new to stackoverflow, so please be gentle with me.
I am currently working my way into objective-c and mac os x development and i am currently stuck at the simple task of binding a few objects together in a small project i am working on:
I have an object AppDelegate, created from a NIB file, containing a NSMutableArray. I wanted to access that array in another class derived from NSOpenGLView (created from the NIB File as well) to iterate the objects stored in it.
How can this be achieved in Interface Builder?
Thanks for your help.
UPDATE: Here is part of my AppDelegate code:
.h:
#interface AppDelegate : NSObject <NSApplicationDelegate> {
IBOutlet NSMutableArray *_players;
}
#property (assign) NSMutableArray *_players;
Additionally i have a MyOpenGLView (implementing NSOpenGLView) where i want to access the objects from the _players Array.
Does your NSOpenGLView have an outlet pointing to your AppDelegate? If not, then you can either make one or use the answer from here.
[(YourAppDelegate *)[[UIApplication sharedApplication] delegate] uploadFiles:array]
(This assumes that AppDelegate actually refers to the application delegate.)
Apple tutorial on interface builder basics (including connecting outlets).

Accessing a label created in the storyboard on current ViewController

I want to do something pretty simple but have yet am having a hard time doing so. I want to access a label created on the currently displayed ViewController (with storyboarding) from that view controller's class. Thanks for any help.
You need to make an IBOutlet Property in your viewcontroller.h and connect it to the label.
After declaring the label property you can click and drag the o next to the property declaration (In Assistive Editor Mode) to the label to make the connection. Dont forget to synthesize it in the m.
#import "ViewController.h"
#implementation ViewController
#synthesize myLabel;
MobileOverlord is right, but you should really start using the Assistant Editor for wiring up things like this. It will do ALL the work for you:
Declaring your property as an IBOutlet
Synthesizing it for you in the implementation file
Setting it to nil in the viewDidUnload method (which you will forget 90% of the time if you do it yourself)
If you have never used the Assistant Editor, you should start it is super easy and helps you concentrate on more important stuff than manually wiring up your outlets AND actions.

Setting a property on a custom object through Interface Builder

I have a custom UITableViewController subclass which I use in two places in a nib file. What should I do if I want the two instances to have slightly different behavior? Of course in the code I can select one kind of behavior or the other based on the value of a BOOL, but how do I set that BOOL from Interface Builder, without having to write an Interface Builder plugin?
As of Xcode 6 there is a new way doing this. You can now give your view properties the attribute IBInspectable and then you can edit those properties in IB as you would with and standard view.
So for example:
#property (nonatomic, strong) IBInspectable BOOL
More details (also for the new attribute IBDesignable) in Apples documentation: https://developer.apple.com/library/ios/recipes/xcode_help-IB_objects_media/chapters/CreatingaLiveViewofaCustomObject.html
"User Defined Runtime Attributes" in the Identity inspector is probably what you're looking for. This seems to be new as of Xcode 4.2.
Unfortunately, there doesn't seem to be much (any?) documentation about this feature on the Apple Developer site. I was able to use it for a simple property set.
So far as I know, you can't set parameters in IB without writing an IB Plugin.
That said, you have two other options.
If it is as simple as a single BOOL, you're probably best off making it a property of the MyCustomViewController class and set it in code after you init:
customViewController = [[MyCustomViewController alloc]initWithNibName:#"CustomViewController" bundle:nil];
[customViewController setFunky:YES];
The other option is to create a protocol for a MyCustomViewDelegate. If you're not familiar with protocols, your header would look like this:
#class MyCustomViewController;
#protocol MyCustomViewDelegate
#required
-(BOOL)customViewShouldBeFunky:(MyCustomViewController*)customView;
#end
#interface MyCustomViewController : UIViewController {
NSObject<MyCustomViewDelegate> *delegate;
}
#property (readwrite, retain) IBOutlet NSObject<MyCustomViewDelegate> *delegate;
#end
Since it is an IBOutlet, you can wire up the delegate like any other delegate in Interface Builder.
Then call [delegate customViewShouldBeFunky:self] when you need to determine how your view should behave.
Have two subclasses is probably easier, and will be easier to document.
Here is an example of overriding properties and setting them in custom classes, this may help. The property code will work before awakeFromNib is called. So you may decide what you have to do based on the user's decision right in awakeFromNib.
https://stackoverflow.com/a/31094561/1699210