У меня есть несколько проблем с NSScrollView, который я пытаюсь использовать, и мне нужна помощь. Я прочитал NSView, NSScrollView и несколько других руководств и справочников, а также вопросы здесь и cocoadev, но до сих пор не могу их понять.
(Код для моего подкласса представления можно найти ниже.)
Моя главная цель - создать интерфейс, подобный интерфейсу KGChart, разработчика диаграмм с иглами, предназначенного исключительно для ПК. (веб-сайт KGChart)
Как я могу сохранить то, что я рисую, в режиме прокрутки? Мой метод -drawStitch выполняется во время событий мыши, где он рисует прямоугольник с символом на нем (в настоящее время только черный с «+») в представление документа в scrollview. Когда я прокручиваю его из виду и обратно, он исчезает, и мне нужно как-то его сохранить. Моя идея состоит в том, чтобы попробовать 2D-массив для отслеживания стежков, но я думаю, что производительность будет ухудшаться с большими холстами (я бы хотел сделать 2,000x2,000, но я бы остановился на 500x500).
Если вы посмотрите на изображение работы моей программы, вы увидите разницу в цвете сетки. Код для рисования сетки находится в -drawRect, а цвет установлен как grayColor. Когда программа запускается, видимая сетка имеет более светлый цвет, но темнее на тех частях холста, которые открываются при прокрутке. Я думаю, что это связано с вызовом -drawRect, заставляющим его перерисовывать сетку, но я не знаю, почему он затемняет штрихи, поскольку их непрозрачность уже должна быть 1.0. Кроме того, если я полностью прокручу исходный кадр и вернусь назад, сетка там также станет темнее.
Есть ли способ нарисовать сетку в начале программы, которой нет в drawRect, чтобы она не перерисовывалась? Я пробовал использовать -awakeFromNib и -initWithFrame даже с -lockFocus, но это не сработало. Я понимаю, что первое, вероятно, не сработало, потому что не было рамки для рисования.
В конце концов, мне нужно будет разобраться в таких вещах, как инструмент заливки и тому подобное, так что было бы лучше использовать для этого что-то вроде Core Graphics, или обычный API в порядке? Я бы предпочел использовать более позднее, поскольку я знаю о нем больше, чем компьютерную графику, но я тоже немного читал об этом.
Заключительные примечания: я использую сборку мусора, и я перевернул представление и окно, в котором оно находится, если это вообще имеет значение.
Изображение запущенной программы:
- (id)initWithFrame:(NSRect)frame {
self = [super initWithFrame:frame];
[self setFrameSize:NSMakeSize(3000, 3000)];
return self;
}
- (void)drawRect:(NSRect)rect {
width = [self frame].size.width;
height = [self frame].size.height;
[[NSColor grayColor] setStroke];
NSBezierPath* drawingPath = [NSBezierPath bezierPath];
[NSBezierPath setDefaultLineWidth:2.0];
[self addDashStyleToPath:drawingPath];
int i;
for( i = 0 ; i <= width ; i=i+30) {
[drawingPath moveToPoint:NSMakePoint(i, 0)];
[drawingPath lineToPoint:NSMakePoint(i, height)];
}
for( i = 0 ; i <= height ; i=i+30) {
[drawingPath moveToPoint:NSMakePoint(0,i)];
[drawingPath lineToPoint:NSMakePoint(width, i)];
}
[drawingPath stroke];
}
-(void)drawStitch{
NSPoint thisPoint;
NSPoint fillPoint;
NSRect fillRect;
float thisPointX = [self calculatedItemBounds].origin.x + 5.0;
float thisPointY = [self calculatedItemBounds].origin.y - 8.0;
float fillPointX = [self calculatedItemBounds].origin.x + 1.0;
float fillPointY = [self calculatedItemBounds].origin.y + 1.0;
thisPoint.x = thisPointX;
thisPoint.y = thisPointY;
fillPoint.x = fillPointX;
fillPoint.y = fillPointY;
fillRect.origin.x = fillPoint.x;
fillRect.origin.y = fillPoint.y;
fillRect.size.width = 28;
fillRect.size.height = 28;
NSMutableDictionary *theAttributes;
theAttributes = [[NSMutableDictionary alloc] init];
[theAttributes setObject: [NSColor whiteColor] forKey:NSForegroundColorAttributeName];
[theAttributes setObject: [NSFont fontWithName:@"Helvetica" size: 32] forKey: NSFontAttributeName];
NSString *theString = @"+";
[self lockFocus];
[[NSColor blackColor] setFill];
[NSBezierPath setDefaultLineWidth:2.0];
[self addDashStyleToPath:[NSBezierPath bezierPathWithRect:[self calculatedItemBounds]]];
[NSBezierPath fillRect:fillRect];
NSNumber* myInteger = [NSNumber numberWithInt:310];
[myArray setObject:myInteger :location.x/30 :location.y/30];
NSLog(@"%@", [myArray objectInSection:location.x/30 :location.y/30]);
NSLog(@"%f, %f", location.x/30,location.y/30);
[theString drawAtPoint:thisPoint withAttributes:theAttributes];
[self displayIfNeededInRectIgnoringOpacity:[self calculatedItemBounds]];
[self unlockFocus];
[theAttributes release];
}
Я, очевидно, довольно нубичен в этом, так что спасибо за вашу помощь!