Cocoa-从nib加载视图,并将其作为子视图显示在NSView容器中
我之前问过这个问题,但是问题本身和其中的所有信息可能有点混乱,加上我想要得到的结果有点复杂。所以我开始了一个新的清洁测试项目来处理我现在感兴趣理解的部分 所以我想要的基本上是:我有一个视图容器(继承NSView)。在内部,我想放置一些图像,但不仅仅是简单的NSImage或NSImageView,而是一些自定义视图(也继承NSView),它本身包含一个文本字段和一个NSImageView。这个我称之为“图像支架”的文件位于一个单独的nib文件中(我使用这种方法,因为我是在苹果示例应用程序COCOA SLIDES之后指导自己的)。 到目前为止,我得到的结果,是一些东西,但不是我所期望的。我想我一定是在界面生成器中做错了什么(没有连接正确的东西),但我希望有更专业的人能够启发我 下面,我将尝试列出我迄今为止拥有的所有代码:Cocoa-从nib加载视图,并将其作为子视图显示在NSView容器中,cocoa,nsview,xib,Cocoa,Nsview,Xib,我之前问过这个问题,但是问题本身和其中的所有信息可能有点混乱,加上我想要得到的结果有点复杂。所以我开始了一个新的清洁测试项目来处理我现在感兴趣理解的部分 所以我想要的基本上是:我有一个视图容器(继承NSView)。在内部,我想放置一些图像,但不仅仅是简单的NSImage或NSImageView,而是一些自定义视图(也继承NSView),它本身包含一个文本字段和一个NSImageView。这个我称之为“图像支架”的文件位于一个单独的nib文件中(我使用这种方法,因为我是在苹果示例应用程序COCOA
//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
//ImagesContainer.h
#进口
@界面图像容器:NSView{
}
@结束
//ImagesContainer.m
#导入“ImagesContainer.h”
#导入“ImageHolderView.h”
#导入“ImageHolderNode.h”
@类ImageHolderView;
@类ImageHolderNode;
@实现图像容器
-(id)initWithFrame:(NSRect)帧{
self=[super initWithFrame:frame];
如果(自我){
//这里是初始化代码。
//创建一些子视图
因为(inti=0;i不是答案,确切地说,因为不清楚你在问什么
创建一个视图(“ImagesContainer”类)。我们将其称为imagesContainerView
ImagesContainerView生成3个对象(类“ImageHolderNode”)。ImagesContainerView向每个ImageHolderNode请求其-rootView
(可能是“ImageHolderView”),并将返回值添加到其视图继承权
ImagesContainerView丢弃(但泄漏)每个imageHolderNode
因此,视图继承人看起来像:-
这是你期待的吗
那么您在哪里调用-(void)loadUIFromNib
并等待nib加载呢?
在某些代码中没有显示
一般来说,一步一步地进行,让每一步都发挥作用
NSAssert是您的朋友。请尝试它,而不是出于调试目的错误地使用警报面板和日志记录
ImageHolderNode *node = [[[ImageHolderNode alloc] init] autorelease];
NSAssert([node rootView], @"Eek! RootView is nil.");
[self addSubview:[node rootView]];
当然,视图应该绘制一些东西。TextView绘制文本,ImageView绘制图像。如果需要绘制除Cocoa提供的文本、图像、表格等以外的其他东西,则应将NSView子类化
如果需要从多个nib组合视图,则应在nib中按照应用程序的要求排列视图,或者使用viewController或windowController。这就是它们的用途
编辑
接口生成器连接
如果RootView不是nil,那么看起来您已经正确连接了您的连接,但是您说您还不清楚
确保IB窗口设置为列表视图,以便您可以清楚地看到nib的内容。
“文件所有者”表示要加载nib的对象,对吗?在您的例子中是ImageHolderNode。
控件单击文件的所有者,以及其他可以看到它的出口的内容。当nib由ImageHolderNode加载时,控件(在列表视图中)从出口拖动到要设置为实例变量的对象。我知道您已经知道了这一点,但除此之外没有其他内容
Doh
你到底希望看到什么?一个空的imageView?好吧,那看起来什么都不像。一个空的textfield?那也会看起来什么都不像。将一个插座连接到你的textfield和imageView,并在它们上设置一些内容。确切地说,这不是答案,因为不清楚你在问什么
创建一个视图(“ImagesContainer”类)。我们将其称为imagesContainerView
ImagesContainerView生成3个对象(类“ImageHolderNode”)。ImagesContainerView向每个ImageHolderNode请求其-rootView
(可能是“ImageHolderView”),并将返回值添加到其视图继承权
ImagesContainerView丢弃(但泄漏)每个imageHolderNode
因此,视图继承人看起来像:-
这是你期待的吗
那么您在哪里调用-(void)loadUIFromNib
并等待nib加载呢?
在某些代码中没有显示
一般来说,一步一步地进行,让每一步都发挥作用
NSAssert是您的朋友。请尝试它,而不是出于调试目的错误地使用警报面板和日志记录
ImageHolderNode *node = [[[ImageHolderNode alloc] init] autorelease];
NSAssert([node rootView], @"Eek! RootView is nil.");
[self addSubview:[node rootView]];
当然,视图应该绘制一些东西。TextView绘制文本,ImageView绘制图像。如果需要绘制除Cocoa提供的文本、图像、表格等以外的其他东西,则应将NSView子类化
如果需要从多个nib组合视图,则应在nib中按照应用程序的要求排列视图,或者使用viewController或windowController。这就是它们的用途
编辑
接口生成器连接
如果RootView不是nil,那么看起来您已经正确连接了您的连接,但是您说您还不清楚
确保IB窗口设置为列表视图,以便您可以清楚地看到nib的内容。
“文件所有者”表示要加载nib的对象,对吗?在您的例子中是ImageHolderNode。
控件单击文件的所有者,以及其他可以看到它的出口的内容。当nib由ImageHolderNode加载时,控件(在列表视图中)从出口拖动到要设置为实例变量的对象。我知道您已经知道了这一点,但除此之外没有其他内容
Doh
你到底希望看到什么?一个空的imageView?嗯,那看起来什么都不像。一个空的textfield?那也会看起来什么都不像。将一个插座连接到你的textfield和imageView,并在它们上设置一些内容。谢谢你的回答。回答你的两个问题:1)我是