tags:

views:

50

answers:

1

I've asked about this earlier but the question itself and all the information in it might have been a little confusing, plus the result i want to get is a little more complicated. So i started a new clean test project to handle just the part that im interested to understand for the moment.

So what i want, is basically this: i have a view container (inherits NSView). Inside, i want to place some images, but not just simple NSImage or NSImageView, but some custom view (inherits NSView also), which itself contains a textfield and an NSImageView. This 'image holder' as i called it, is in a separate nib file (im using this approach since i am guiding myself after an Apple SAmple Application, COCOA SLIDES). The results i got so far, is something but not what i am expecting. Im thinking i must be doing something wrong in the Interface Builder (not connecting the proper thingies), but i hope someone with more expertise will be able to enlighten me.

Below i'll try to put all the code that i have so far:

//ImagesContainer.h
#import <Cocoa/Cocoa.h>


@interface ImagesContainer : NSView {

}
@end
//ImagesContainer.m
#import "ImagesContainer.h"
#import "ImageHolderView.h"
#import "ImageHolderNode.h"
@class ImageHolderView;
@class ImageHolderNode;
@implementation ImagesContainer

- (id)initWithFrame:(NSRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code here.
  //create some subviews
  for(int i=0;i<3;i++){
   ImageHolderNode *node = [[ImageHolderNode alloc] init];
   [self addSubview:[node rootView]];
  }
    }
 NSRunAlertPanel(@"subviews", [NSString stringWithFormat:@"%d",[[self subviews] count]], @"OK", NULL, NULL);
    return self;
}

- (void)drawRect:(NSRect)dirtyRect {
    // Drawing code here.

 [[NSColor blackColor] set];
 NSRectFill(NSMakeRect(0,0,dirtyRect.size.width,dirtyRect.size.height));
 int i=1;
 for(NSView *subview in [self subviews]){
  [subview setFrameOrigin:NSMakePoint(10*i, 10)];
  i++;
 }
}

@end

//ImageHolderView.h
#import <Cocoa/Cocoa.h>


@interface ImageHolderView : NSView {
 IBOutlet NSImageView *imageView;
}
@end
//ImageHolderVIew.m
#import "ImageHolderView.h"


@implementation ImageHolderView
- (id)initWithFrame:(NSRect)frame {
    self = [super initWithFrame:frame];
    if (self) {

    }
    return self;
}

- (void)drawRect:(NSRect)dirtyRect {
    // Drawing code here.
 [[NSColor blueColor]set];
 NSRectFill(NSMakeRect(10,10, 100, 100));
 //[super drawRect:dirtyRect];
}
@end

//ImageHolderNode.h
#import <Cocoa/Cocoa.h>
@class ImageHolderView;

@interface ImageHolderNode : NSObject {
 IBOutlet ImageHolderView *rootView;
 IBOutlet NSImageView *imageView;
}
-(NSView *)rootView;
-(void)loadUIFromNib;
@end

//ImageHolderNode.m
#import "ImageHolderNode.h"


@implementation ImageHolderNode

-(void)loadUIFromNib {
 [NSBundle loadNibNamed:@"ImageHolder" owner: self];
}
-(NSView *)rootView {
 if( rootView == nil) {
  NSRunAlertPanel(@"Loading nib", @"...", @"OK", NULL, NULL);
  [ self loadUIFromNib];
 }
 return rootView;
}

@end

My nib files are:

  1. MainMenu.xib
  2. ImageHolder.xib

  3. MainMenu is the xib that is generated when i started the new project.

  4. ImageHolder looks something like this: image link

I'll try to mention the connections so far in the xib ImageHolder :

File's Owner - has class of ImageHolderNode The main view of the ImageHolder.xib , has the class ImageHolderView

So to resume, the results im getting are 3 blue rectangles in the view container, but i cant seem to make it display the view loaded from the ImageHolder.xib

If anyone wants to have a look at the CocoaSlides sample application , its on apple developer page ( im not allowed unfortunately to post more than 1 links :) )

A: 

Not an answer, exactly, as it is unclear what you are asking..

You make a view (class 'ImagesContainer'). Lets call it imagesContainerView.

ImagesContainerView makes 3 Objects (class 'ImageHolderNode'). ImagesContainerView asks each imageHolderNode for it's -rootView (maybe 'ImageHolderView') and adds the return value to it's view-heirarchy.

ImagesContainerView throws away (but leaks) each imageHolderNode.

So the view heirachy looks like:-

+ imagesContainerView
    + imageHolderView1 or maybe nil
    + imageHolderView2 or maybe nil
    + imageHolderView3 or maybe nil

Is this what you are expecting?

So where do you call -(void)loadUIFromNib and wait for the nib to load?
In some code you are not showing?

In general, progress a step at a time, get each step working.

NSAssert is your friend. Try it instead of mis-using alert panels and logging for debugging purposes. ie.

ImageHolderNode *node = [[[ImageHolderNode alloc] init] autorelease];
NSAssert([node rootView], @"Eek! RootView is nil.");
[self addSubview:[node rootView]];

A view of course, should draw something. TextViews draw text and ImageViews draw images. You should subclass NSView if you need to draw something other than text, images, tables, etc. that Cocoa provides.

You should arrange your views as your app requires in the nib or using a viewController or a windowController if you need to assemble views from multiple nibs. Thats what they are for.

EDIT

Interface Builder Connections

If RootView isn't nil then it seems like you have hooked up your connections correctly, but you say you are unclear so..

Make sure the IB window is set to List view so you can see the contents of you nib clearly.
'File's Owner' represents the object that is going to load the nib, right? In your case ImageHolderNode.
Control Click on File's owner and amongst other things you can see it's outlets. Control drag (in the list view) from an outlet to the object you want to be set as the instance var when the nib is loaded by ImageHolderNode. I know you know this already, but there is nothing else to it.

Doh

What exactly are you expecting to see ? An empty imageView? Well, that will look like nothing. An empty textfield? That too, will look like nothing. Hook up an outlet to your textfield and imageView and set some content on them.

mustISignUp
Thanks for the answer. To answer two of your questions: 1) I am asking why in the container, i dont see the view i created in InterfaceBuilder ( i only get the blue fill that im doing in -drawRect of the ImageHolderView )2) Where do I load the nib : that is done in the implementation of ImageHOlderNode, in the body of -(NSView *)rootView . I'd be happy to use another way to do this, but since the Apple example was my only source of `inspiration` so far, im trying to use stuff i find there.
eemerge
Ok, i see. So you need to examine the rootView. Is it the view you think it is? ie. did you hook it up correctly? How many subviews does it have, what position etc..
mustISignUp
By hooking up, you reffer to hooking it up in the InterfaceBuilder? If yes, i would like some advice on this, since im kinda lost in all the hooking process :) I tried to hook it up as close to the hooking up in the sample app that im using as a guide, but maybe i didn't do it properly.Ok, i just did a quick test, i displayed the number of subviews that rootView has: it should have 2 subviews (1 textfield and 1 nsimageview), and it does have 2 . So i guess its loading ok, but still not being displayed properly.
eemerge
If i have some content in the NSText field, shouldnt it be displayed? I thought about the NSImageView that it cannot display anything since there's nothing set on it to display, but if the textfield has some content in the IB i figured it should have had displayed. I'll look into this and come back.
eemerge
All working now, thanks a lot! :)
eemerge