Я изучаю программирование на Какао и не могу понять, как
архивировать и разархивировать пользовательский подкласс NSView
Я сделал игрушечное приложение, которое представляет окно. Это окно
содержит экземпляр моего пользовательского класса BackgroundView (архивируется в
XIB-файл). Щелчок в любом месте этого BackgroundView создает и
отображает синий квадрат, источником которого является точка щелчка. Этот квадрат
экземпляр моего квадратного класса. Все это работает, как я ожидаю.
Класс Square реализует протокол NSCoding. Я добавил
dataOfType: typeName: ошибка: и readfromData: ofType: ошибка: методы
в класс MyDocument. Насколько я могу судить по операторам журнала,
Квадраты архивируются в файл и разархивируются, когда файл
загружен. Но я не могу заставить квадратики отображаться на
окно. DrawWithRect: метод класса Square никогда не вызывается,
хотя я вызывал setNeedsDisplay: YES на каждом квадрате.
Код выглядит следующим образом:
Square.h
#import <Cocoa/Cocoa.h>
@interface Square : NSView <NSCoding> {
}
@end
Square.m
#import "Square.h"
@implementation Square
- (id)initWithFrame:(NSRect)frame {
self = [super initWithFrame:frame];
return self;
}
- (void)drawRect:(NSRect)rect {
[[NSColor blueColor] set];
NSBezierPath *newPath = [NSBezierPath bezierPathWithRect:[self bounds]];
[newPath fill];
}
-(void)encodeWithCoder:(NSCoder *)coder
{
[coder encodeRect:[self frame] forKey:@"frame"];
}
-(id)initWithCoder:(NSCoder *)coder
{
NSRect theRect = [coder decodeRectForKey:@"frame"];
self = [super initWithFrame:theRect];
return self;
}
@end
-----
BackgroundView.h
#import <Cocoa/Cocoa.h>
@interface BackgroundView : NSView {
}
@end
BackgroundView.m
#import "BackgroundView.h"
#import "Square.h"
@implementation BackgroundView
- (id)initWithFrame:(NSRect)frame {
self = [super initWithFrame:frame];
if (self) {
// Initialization code here.
}
return self;
}
- (void)drawRect:(NSRect)rect {
for (Square *subview in self.subviews)
[subview setNeedsDisplay:YES];
}
-(void)mouseDown:(NSEvent *)theEvent {
NSPoint unsetClick = [theEvent locationInWindow];
NSPoint theClick = [self convertPoint:unsetClick fromView:nil];
NSRect theRect;
theRect.origin = theClick;
theRect.size.width = 100.00;
theRect.size.height = 100.00;
Square *newSquare = [[Square alloc] initWithFrame:theRect];
[self addSubview:newSquare];
[newSquare setNeedsDisplay:YES];
}
@end
------
MyDocument.h
#import <Cocoa/Cocoa.h>
@class BackgroundView;
@interface MyDocument : NSDocument
{
IBOutlet BackgroundView *theBackgroundView;
}
@end
MyDocument.m
#import "MyDocument.h"
@implementation MyDocument
- (id)init
{
self = [super init];
return self;
}
- (NSString *)windowNibName
{
return @"MyDocument";
}
- (void)windowControllerDidLoadNib:(NSWindowController *) aController
{
[super windowControllerDidLoadNib:aController];
}
- (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError
{
return [NSKeyedArchiver
archivedDataWithRootObject:[theBackgroundView subviews]];
if ( outError != NULL ) {
*outError = [NSError errorWithDomain:NSOSStatusErrorDomain
code:unimpErr userInfo:NULL];
}
return nil;
}
- (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName
error:(NSError **)outError
{
[theBackgroundView setSubviews:[NSKeyedUnarchiver
unarchiveObjectWithData:data]];
[theBackgroundView setNeedsDisplay:YES];
if ( outError != NULL ) {
*outError = [NSError errorWithDomain:NSOSStatusErrorDomain
code:unimpErr userInfo:NULL];
}
return YES;
}
@end