Binding in Interface Builder - objective-c

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

Related

What Happened to Core Data Bindings?

I've been out of the loop for a while, but it used to be you could use Interface Builder to add an NSArrayController, set it's mode to Entity, and bind the managedObjectContext to the MOC of the AppDelegate. That doesn't seem to work anymore.
I've read through the documentation, (of course it's very possible I missed something) but I haven't yet found a way to bind my Array Controller to my Core Data stack. Somewhere along the line things got "simplified". What is the preferred way to get objects from Core Data to my NSTableView?
For more details, I currently have a fairly empty non-document project, no storyboards, with no modifications to the App Delegate, but I did add a property on my App Controller to access the MOC:
#interface JBAppController : NSObject
#property (nonatomic, readonly) NSManagedObjectContext* managedObjectContext;
#end
#implementation JBAppController
...
- (NSManagedObjectContext*)managedObjectContext
{
return [[(AppDelegate *)[[NSApplication sharedApplication] delegate] persistentContainer] viewContext];
}
...
I'll probably redo this once I understand what the bindings are missing, or if we aren't meant to use bindings anymore, however the right way to get the data to the tableview is.
Control-drag:
Control-drag to the property, configure the binding and click on Connect.
Bindings Inspector:
Configure the binding and turn on the Bind to checkbox.

How to hook up NSWindowDelegate in macOS game template

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.

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!

Declaring IBOutlet inside or outside #interface?

sorry If am I being too picky on this one but I am learning iOS programming now and I've seem some people who declare the IBOutlet like this:
IBOutlet attached to property
#import <UIKit/UIKit.h>
#import "CustomCell.h"
#interface CustomTableViewController : UITableViewController {
CustomCell *customCell;
}
#property (nonatomic, retain) IBOutlet CustomCell *customCell;
#end
And some declaring like this:
IBOutlet attached to the declaration inside the interface
#import <UIKit/UIKit.h>
#import "CustomCell.h"
#interface CustomTableViewController : UITableViewController {
IBOutlet CustomCell *customCell;
}
#property (nonatomic, retain) CustomCell *customCell;
#end
which one is the proper way to declare it? Are any differences between them?
If someone know to explain why do they put it on different places it would be awesome to learn.
Thanks a lot :)
Both of those are still "inside the interface" so your title it a bit confusing but I see what you are asking.
In many cases the result of either approach will be the same but they are different. An IBOutlet property will call the property's setter method which gives you an opportunity to override that setter if setting that property should have some side effect.
I prefer to use outlets on properties because I think it makes the memory management of the objects loaded from the nib much clearer. Take a look at memory management of nib objects and I think you will see what I mean.
Objects in the nib file are created with a retain count of 1 and then autoreleased. As it rebuilds the object hierarchy, UIKit reestablishes connections between the objects using setValue:forKey:, which uses the available setter method or retains the object by default if no setter method is available. This means that (assuming you follow the pattern shown in “Outlets”) any object for which you have an outlet remains valid. If there are any top-level objects you do not store in outlets, however, you must retain either the array returned by the loadNibNamed:owner:options: method or the objects inside the array to prevent those objects from being released prematurely.
IBOutlet ivars will call setters for those ivars if they exists and directly retain the object loaded from the nib if no setter is found.
Advertising the property as the IBOutlet at least makes it clear that the property's setter will always be used and follow whatever memory management rule has been set for that property.
Finally I argue that IBOutlets are part of the public interface of a class and it is therefore better to expose methods (via a property) for working with them eager than using -setValue:forKey: to manipulate the backing ivars which should be an implementation detail.
The two styles are interchangeable, there is no difference in the generated code or the way objects will be loaded from a nib. Really.
However, both styles have a redundant line. Simply leave out the ivar declaration. Just the line
#property (nonatomic, retain) IBOutlet CustomCell *customCell;
is sufficient in the modern runtime.
If you have a complex project, I suggest moving all the outlets out of the public interface into a separate header file. Most outlets are private interface, the only reason to have them in a header is so Interface Builder can find them.
You can declare both ways, there is no difference actually.
But, here is the thing:
If you need your class to have some ivar with a special behavior or it has to be accessed from outside, etc, and it has to be a property, then I will say you have 2 options to choose from (attached to the property and inside the class interface).
If that is not your case, don't create a property, is not necessary, just do it inside your class interface.
Hope it helps ;)

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