首页 文章

Cocoa - 从nib加载视图并将其显示在NSView容器中,作为子视图

提问于
浏览
2

我之前已经问过这个问题,但问题本身及其中的所有信息可能有点令人困惑,加上我想得到的结果有点复杂 . 所以我开始了一个新的清洁测试项目来处理我目前感兴趣的部分 .

所以我想要的,基本上是这样的:我有一个视图容器(继承NSView) . 在里面,我想放置一些图像,但不只是简单的NSImage或NSImageView,而是一些自定义视图(也继承NSView),它本身包含一个文本字段和一个NSImageView . 我称之为“图像持有者”,是在一个单独的nib文件中(我使用这种方法,因为我在Apple SAmple应用程序之后引导自己,COCOA SLIDES) . 到目前为止,我得到的结果不是我所期待的 . 我想我必须在Interface Builder中做错事(没有连接正确的东西),但我希望有更多专业知识的人能够启发我 .

下面我将尝试将我目前所有的代码放入:

//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

我的nib文件是:

  • MainMenu.xib

  • ImageHolder.xib

  • MainMenu是我启动新项目时生成的xib .

  • ImageHolder看起来像这样:image link

我将尝试在xib ImageHolder中提及到目前为止的连接:

File的所有者 - 拥有ImageHolderNode类ImageHolder.xib的主视图,具有ImageHolderView类

所以要恢复,结果我得到的是视图容器中的3个蓝色矩形,但我似乎无法让它显示从ImageHolder.xib加载的视图

如果有人想看看CocoaSlides示例应用程序,那么它在Apple开发者页面上(不幸的是,我不允许发布超过1个链接:))

1 回答

  • 0

    完全不是答案,因为不清楚你在问什么......

    你创建了一个视图(类'ImagesContainer') . 我们称之为 imagesContainerView .

    ImagesContainerView生成3个对象(类'ImageHolderNode') . ImagesContainerView要求每个imageHolderNode为 -rootView (也许是'ImageHolderView'),并将返回值添加到它的view-heirarchy中 .

    ImagesContainerView抛弃(但泄漏)每个imageHolderNode .

    所以heirachy看起来像: -

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

    这是你期待的吗?

    那么你在哪里调用 -(void)loadUIFromNib 并等待nib加载?
    在某些代码中你没有显示?

    一般来说,一步一步进步,让每一步都有效 .

    NSAssert是你的朋友 . 尝试使用它而不是误用警报面板和日志记录以进行调试 . 即 .

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

    一个观点当然应该画出一些东西 . TextViews绘制文本,ImageViews绘制图像 . 如果你需要绘制Cocoa提供的文本,图像,表格等以外的东西,你应该继承NSView .

    如果您需要从多个笔尖组装视图,您应该在笔尖中根据应用需要安排视图,或者使用viewController或windowController . 这就是它们的用途 .

    编辑

    Interface Builder连接

    如果RootView不是nil,那么好像你已经正确地连接了你的连接,但你说你不清楚这样......

    确保IB窗口设置为列表视图,以便您可以清楚地看到笔尖的内容 .
    'File' s所有者'代表要加载笔尖的对象,对吧?在你的情况下ImageHolderNode .
    控制单击文件's owner and amongst other things you can see it'的插座 . 当ImageHolderNode加载nib时,控制从插座拖动(在列表视图中)到要设置为实例var的对象 . 我知道你已经知道了,但没有别的 .

    Doh

    你到底想要看到什么?一个空的imageView?好吧,那看起来什么都没有 . 一个空的文本域?那也是什么都没有 . 连接文本域和imageView的插座并在其上设置一些内容 .

相关问题