allocating view controller the right way - macos

i am trying to archiv something really simple.
I add a property for a NSScrollView in my ViewController header file called PanelController:
#property (strong) IBOutlet NSScrollView *listurls_fld;
I add the ViewController.h file to my NSObject Interface called "qhandler.h"
#import "handler.h"
#import "PanelController.h"
i have a +(void) function inside the qhandler.m ->
+ (void)do_handle:(NSDictionary *)response
{
PanelController *MyView=[[PanelController alloc] init];
NSLog(#"add moo");
[MyView.listurls_fld setStringValue:#"moo"];
}
which doesn't work...
It does neither work with setAlphaValue or whatever, i guess it's because i am allocating a new instance of PanelController, but as a matter of fact, I tried to change the main instance.
I know it's basic but i have enormous problems using IBOutlets from a viewcontroller, inside an external obj-c file.
Thanks,
john

ViewController.h
id mainDelegate;
ViewController.m
in viewDidLoad oder what function ever triggers after load:
mainDelegate=self;
so i can use [mainDelegate ...:..]; in every file..

Related

Set view as delegate to viewcontroller

I'm having problem passing data and executing functions in the viewcontroller from the view. I want to access label outlets in the viewcontroller from the view (yeah I know it might be bad structure of my app).
Got delegations working on UIPopovers but how can I set the delegate of the view to viewcontroller?
For example, you have a subclass of UIView. Let's name it SubClassUIView;
In another view, you want to use the data, from SubClassUIView.
So, your SubClassUIView should be done like this:
SubClassUIView.h
#interface SubClassUIView:UIView
#property (nonatomic, retain) UILabel* someLabelYouWantToUse;
#end.
SubClassUIView.m
#implementation SubClassUIView
#synthesize someLabelYouWantToUse;
#end.
And to access someLabelYouWantToUse
SubClassUIView* scView = [SubClassUIView alloc]init];
NSLog(#"%#", scView.someLabelYouWantToUse.text);

Outlets and instance methods

I have a little problem and hope that you can help me.
I want to call a instance method of a subclassed window and set the user interface up there:
//AppDelegate.h
#import <Cocoa/Cocoa.h>
#class MainView;//The main window
#interface DownloadedAppDelegate : NSObject <NSApplicationDelegate> {
IBOutlet MainView*mainview;//the objects are in the same nib, outlet connected with the window
}
#property(nonatomic,retain) IBOutlet MainView*mainview;
#end
.
//AppDelegate.m
#import "MainView.h"
#synthesize mainview;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
[mainview launched];//But sometimes this code fails, I don't know why
//launched sets up the interface
}
-(void)dealloc {
mainview=nil;
}
MainView belongs to NSWindow.
Is there something wrong or something to improve? Should I build up the UI somewhere else? Do you know why this code does not work always?
Try putting
[mainview launched];
in
-(void)awakeFromNib {
}
Use the debugger! Is launched even getting called?
Set a break point at the launched call and look at the value of mainview. It is nil? This is because outlets are not guaranteed to be connected until awakeFromNib.

Can't load an NSMutableArray with UIView objects

On my game board (which is called GameViewController), I have six Seats (in the xib) which are nothing more than subclassed UIViews (so I also have Seat.h and .m files in my project). When the game board gets initialized these seats also get created (thanks to the xib). I want to have the seats loaded into an NSMutableArray so that I can use them later. For some reason I can't get it to work.
In my GameViewController header file I've added NSMutableArray *seats; as an instance variable and included #class Seat; above the interface declaration.
In my awakeFromNib method of the GameViewController I have seats = [[NSMutableArray arrayWithCapacity:6] retain]; So the array should be initialized when the game board appears.
Then in my Seat header file I've included GameViewController *controller; as an instance variable and included #class GameViewController above the interface declaration. I've also added and synthesized a property for the GameViewController.
In the Seat's awakeFromNib method I have [controller registerSeat:self];
This calls a method in my GameViewController that has only one line: [seats addObject:seat]; This should add the seat to the array. But for some reason this method never seems to get called. Or if it does, I can never tell. When I debug, focus never goes to the registerSeat method even though the seats do get added to the board. I hope this all makes sense. If the code is needed, I can provide it. It might be easier to do that anyway. What do you guys think? I'm stumped at the moment.
The method declaration is as follows:
- (void) registerSeat:(Seat *)seat;
GameViewController.h:
#import <UIKit/UIKit.h>
#class Seat;
#interface GameViewController : UIViewController {
NSMutableArray *seats;
}
- (void) registerSeat:(Seat *)seat;
#end
GameViewController.m
#import "GameViewController.h"
#import "Seat.h"
#implementation GameViewController
- (void)awakeFromNib {
seats = [[NSMutableArray arrayWithCapacity:6] retain];
}
- (void) registerSeat:(Seat *)seat {
[seats addObject:seat];
NSLog(#"seat has been registered");
}
#end
Seat.h:
#import <UIKit/UIKit.h>
#class GameViewController;
#interface Seat : UIView {
GameViewController *controller;
}
#property (nonatomic, retain) IBOutlet GameViewController *controller;
#end
Seat.m:
#import "Seat.h"
#import "GameViewController.h"
#implementation Seat
#synthesize controller;
- (void) awakeFromNib {
[controller registerSeat:self];
}
#end
What you're doing here is what Xcode 4's IBOutletCollection is designed to solve. In your NIB, select all of your Seat views (these should be called SeatView, BTW. Seat should be a model class, not a view class). Drag the selected group to your GameViewController header and request an IBOutletCollection. This will wire them all as a random-ordered array. (Why they chose to make it a random-ordered array is beyond me; it's a somewhat insane construct, but it exactly matches what you're trying to do above.)
As #highlycaffeinated notes, the most likely reason for your current code failing is that you've failed to wire your controller and it's nil. When "nothing happens" in Objective-C, it's almost always because you're talking to nil.

Getting around IBActions limited scope

I have an NSCollectionView and the view is an NSBox with a label and an NSButton. I want a double click or a click of the NSButton to tell the controller to perform an action with the represented object of the NSCollectionViewItem. The Item View is has been subclassed, the code is as follows:
#import <Cocoa/Cocoa.h>
#import "WizardItem.h"
#interface WizardItemView : NSBox {
id delegate;
IBOutlet NSCollectionViewItem * viewItem;
WizardItem * wizardItem;
}
#property(readwrite,retain) WizardItem * wizardItem;
#property(readwrite,retain) id delegate;
-(IBAction)start:(id)sender;
#end
#import "WizardItemView.h"
#implementation WizardItemView
#synthesize wizardItem, delegate;
-(void)awakeFromNib {
[self bind:#"wizardItem" toObject:viewItem withKeyPath:#"representedObject" options:nil];
}
-(void)mouseDown:(NSEvent *)event {
[super mouseDown:event];
if([event clickCount] > 1) {
[delegate performAction:[wizardItem action]];
}
}
-(IBAction)start:(id)sender {
[delegate performAction:[wizardItem action]];
}
#end
The problem I've run into is that as an IBAction, the only things in the scope of -start are the things that have been bound in IB, so delegate and viewItem. This means that I cannot get at the represented object to send it to the delegate.
Is there a way around this limited scope or a better way or getting hold of the represented object?
Thanks.
Firstly, you almost never need to subclass views.
Bind doesn't do what you think - you want addObserver:forKeyPath:options:context: (You should try to understand what -bind is for tho ).
When you say "the key seems to be it being the "prototype" view for an NSCollectionViewItem" I think you are really confused…
Forget IBOutlet & IBAction - they don't mean anything if you are not Interface Builder. "Prototype" means nothing in Objective-c.
The two methods in the view do not have different scope in any way - there is no difference between them at all. They are both methods, equivalent in every way apart from their names (and of course the code they contain).
If wizardItem is null in -start but has a value in -mouseDown this is wholly to do with the timing that they are called. You either have an object that is going away too soon or isn't yet created at a point you think it is.
Are you familiar with NSZombie? You will find it very useful.

What's wrong with this Cocoa code?

I'm trying to make a simple Cocoa application using XCode 3.2.3. In interface builder I added NSTextField and NSButton. When I press the button, I want it to clear whatever is in the text field.
I made a new class called AppController.h. This is the contents:
#import <Foundation/Foundation.h>
#interface AppController : NSObject {
IBOutlet id textView;
}
- (IBAction) clearText: sender;
#end
AppController.m looks like this:
#import "AppController.h"
#implementation AppController
- (IBAction) clearText: sender
{
[textView setString: #" "];
}
#end
I connected the button to clearText and the textbox to textView.
The program compiles without error and runs. But when I press the button, nothing happens. Why is that?
Using id for an IBOutlet is a bad practice. Use
IBOutlet NSTextView* textView;
instead.
Please check using the debugger, or putting NSLog(#"foo!"); before [textView setString:#""] to see if the action method is really called.
Another pitfall is that there are NSTextView and NSTextField. These two are different!
The former supports both setString: and setStringValue:, while the latter only supports setStringValue:.
Which object did you use in the interface builder?

Resources