Какао - загрузка представления из пера и отображение его в контейнере NSView как подпредставление - PullRequest
2 голосов
/ 21 июня 2010

Я спрашивал об этом ранее, но сам вопрос и вся информация в нем, возможно, были немного запутанными, плюс результат, который я хочу получить, немного сложнее. Поэтому я запустил новый чистый тестовый проект, предназначенный только для той части, которая мне сейчас интересна.

Так что я хочу, в основном это: у меня есть контейнер представления (наследует NSView). Внутри я хочу разместить несколько изображений, но не просто простой NSImage или NSImageView, но некоторое пользовательское представление (также наследует NSView), которое само содержит текстовое поле и NSImageView. Этот «держатель изображения», как я его назвал, находится в отдельном nib-файле (я использую этот подход, поскольку я руководствуюсь после Apple SAmple Application, COCOA SLIDES). Результаты, которые я получил до сих пор, это нечто, но не то, что я ожидаю. Я думаю, что, должно быть, я делаю что-то не так в Интерфейсном Разработчике (не соединяя нужные вещи), но я надеюсь, что кто-то с большим опытом сможет меня просветить.

Ниже я постараюсь поместить весь код, который у меня есть:

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

Мои файлы пера:

  1. MainMenu.xib
  2. ImageHolder.xib

  3. MainMenu - это xib, который создается при запуске нового проекта.

  4. ImageHolder выглядит примерно так: ссылка на изображение

Я попытаюсь упомянуть соединения в xib ImageHolder до сих пор:

Владелец файла - имеет класс ImageHolderNode Основной вид ImageHolder.xib, имеет класс ImageHolderView

Итак, чтобы возобновить, результаты, которые я получаю, представляют собой 3 синих прямоугольника в контейнере вида, но я не могу заставить его отображать представление, загруженное из ImageHolder.xib

Если кто-то захочет взглянуть на пример приложения CocoaSlides, он находится на странице разработчика Apple (к сожалению, я не могу размещать более 1 ссылки :))

1 Ответ

0 голосов
/ 22 июня 2010

Точно не ответ, так как неясно, о чем вы спрашиваете.

Вы делаете представление (класс 'ImagesContainer') .Давайте назовем это imagesContainerView .

ImagesContainerView создает 3 объекта (класс 'ImageHolderNode').ImagesContainerView запрашивает у каждого imageHolderNode его -rootView (возможно, 'ImageHolderView') и добавляет возвращаемое значение к его иерархии вида.

ImagesContainerView отбрасывает (но пропускает) каждый imageHolderNode.

Итак, иерархия представлений выглядит следующим образом: -

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

Это то, что вы ожидаете?

Итак, куда вы звоните -(void)loadUIFromNib и ждете загрузки пера?
В каком-то коде, который вы не видите?

В общем, выполняйте шаг за шагом, получитекаждый шаг работает.

NSAssert - ваш друг.Попробуйте вместо неправильного использования панелей оповещения и ведения журнала в целях отладки.то есть.

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

А вид, конечно, должен что-то нарисовать.TextViews рисуют текст, а ImageViews рисуют изображения.Вы должны создать подкласс NSView, если вам нужно нарисовать что-то, кроме текста, изображений, таблиц и т. Д., Которые предоставляет Какао.

Вы должны расположить ваши представления так, как требует ваше приложение, в виде кончика или использования viewController или windowController, есливам нужно собрать представления из нескольких перьев.Вот для чего они нужны.

РЕДАКТИРОВАТЬ

Соединения Interface Builder

Если RootView не равен нулю, то кажется, что вы правильно подключили свои соединения, но вы говорите, чтонеясно, поэтому ..

Убедитесь, что окно IB установлено в виде списка, чтобы вы могли четко видеть содержимое вашего пера.
«Владелец файла» представляет объект, который будет загружать перо,право?В вашем случае ImageHolderNode.
Контроль Нажмите на владельца файла и, среди прочего, вы увидите его выходы.Управляйте перетаскиванием (в виде списка) из розетки к объекту, который вы хотите установить в качестве экземпляра var при загрузке кончика ImageHolderNode.Я знаю, что вы уже знаете это, но больше ничего нет.

Doh

Что именно вы ожидаете увидеть?Пустой imageView?Ну, это будет выглядеть как ничто.Пустое текстовое поле?Это тоже будет выглядеть как ничто.Подключите выход к вашему текстовому полю и imageView и установите некоторый контент на них.

...