Проблемы NSScrollView - PullRequest
       40

Проблемы NSScrollView

4 голосов
/ 06 июля 2011

У меня есть несколько проблем с NSScrollView, который я пытаюсь использовать, и мог бы использовать некоторую помощь. Я прочитал NSView, NSScrollView и несколько других руководств и ссылок, наряду с вопросами здесь и cocoadev, но все еще не могу понять это.

(Код для моего подкласса представления может быть найден ниже.)

Моя общая цель с этим - интерфейс, подобный интерфейсу для KGChart, производителя игольчатых карт, который является эксклюзивным для ПК. ( сайт KGChart )

  1. Как сохранить вещи, которые я рисую, в виде прокрутки? Мой метод -drawStitch выполняется во время событий мыши, когда он рисует прямоугольник с символом на нем (в настоящее время только черный с «+») для представления документа представления прокрутки. Когда я прокручиваю его из поля зрения и обратно, он исчезает, и мне нужно как-то его сохранить. Моя идея состоит в том, чтобы попробовать 2D-массив для отслеживания стежков, но я думаю, что производительность может ухудшиться на больших холстах (я хотел бы сделать 2000x2000, но я бы согласился на 500x500).

  2. Если вы посмотрите на картинку моей программы, вы увидите разницу в цвете сетки. Код для рисования сетки находится в -drawRect, а цвет установлен как grayColor. Когда программа запускается, видимая сетка имеет более светлый цвет, но она темнее на тех частях холста, которые отображаются при прокрутке. Я думаю, что это связано с вызовом -drawRect, заставляя его перерисовывать сетку, но я не знаю, почему это затемняет штрихи, поскольку их непрозрачность должна быть уже 1,0. Кроме того, если я полностью прокручиваю исходную рамку и возвращаюсь назад, сетка там тоже темнее.

  3. Могу ли я нарисовать сетку в начале программы, которая не находится в drawRect, чтобы она не перерисовывалась? Я пробовал в -awakeFromNib и -initWithFrame, даже с -lockFocus, но это не сработало. Я понимаю, что первое, вероятно, не сработало, потому что не было рамки для рисования.

  4. В конце концов мне нужно будет разобраться с такими вещами, как инструмент заливки и тому подобное, так что лучше было бы использовать что-то вроде Core Graphics для этого, или обычный API в порядке? Я предпочел бы использовать позже, так как знаю больше, чем CG, но я тоже немного читал об этом.

Заключительные замечания: я использую сборщик мусора, и я перевернул вид и окно, в котором он находится, если это вообще имеет значение.

Изображение работающей программы:

Picture of the program running

    - (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];
}

Я, конечно, довольно нубистен, поэтому спасибо за вашу помощь!

Ответы [ 2 ]

2 голосов
/ 06 июля 2011

По умолчанию представление содержимого (экземпляр NSClipView) NSScrollView выполняет некоторую оптимизацию производительности, копируя существующее визуализированное изображение при прокрутке.В большинстве случаев это работает нормально, но когда вы рисуете сложное настраиваемое представление, это часто нежелательное поведение, поэтому вам следует отключить его.

Если вы используете перо для определения своего пользовательского интерфейса, просто выберитепрокрутите представление в IB и снимите флажок «Копии при прокрутке».

Вы можете установить это программно, используя ‑setCopiesOnScroll: метод NSClipView:

[[scrollView contentView] setCopiesOnScroll:NO];
1 голос
/ 13 июля 2011

Я верю, что исправил это.Чтобы это работало, мне пришлось переставить свой код, чтобы рисовать в drawRect, а не использовать lockFocus в моем методе drawStitch (мне нужно ознакомиться с проектированием MVC).Кроме того, вид прокрутки, кажется, только перерисовывает последний путь Безье, поэтому для создания нескольких «стежков» мне нужно продолжать добавлять путь с помощью rects.

...