Нарисовать форму сигнала в NSView

#objective-c #cocoa #opengl #animation #nsview

#objective-c #какао #opengl #Анимация #nsview

Вопрос:

Мне нужно нарисовать форму волны в NSView. (У меня есть все выборки в массиве). Рисование должно быть эффективным и действительно быстрым, Без обрезки, мерцания и т. Д., Оно должно быть плавным. Форма сигнала будет «перемещаться» в соответствии с положением песни, и некоторые изменения в сэмплах (обработка DSP) будут показаны в виде визуального представления в NSView в режиме реального времени.

Я знаком с рисованием линий, дуг и т. Д. На объектах canvas, и я разработал приложения, делающие такие вещи, но не на Mac OS X…

Я хочу спросить, может ли кто-нибудь подсказать мне, с чего начать рисовать! Основная анимация, OpenGL, простые переопределяющие методы рисования, ?? и т.д. Какой API-интерфейс лучше всего использовать?

Ответ №1:

Я бы сделал это просто и создал NSView подкласс со audioData свойством, которое использует рисование Cocoa. Вы могли бы вызвать [view setAudioData:waveArray] который, в свою очередь, вызовет [self setNeedsDisplay:YES] .

Затем в вашем drawRect: методе вы можете перебирать выборки и использовать NSRectFill() их соответствующим образом. Здесь sample value значение находится между 0 и 1.

 - (void)drawRect:(NSRect)dirtyRect {
    [[NSColor blueColor]set];
    for (id sample in self.waveArray) {
        NSRect drawingRect = NSZeroRect;
        drawingRect.origin.x = [self bounds].origin.x;
        drawingRect.origin.y = [self bounds].origin.y   ([self.waveArray indexOfObject:sample]/([self.waveArray count] - 1.0));
        drawingRect.size.width = [self bounds].size.width/[self.waveArray count];
        drawingRect.size.height = [self bounds].size.height * [sample value];
        NSRectFill(drawingRect);
    }
}
 

Этот код не является точным, и вы должны быть уверены, что сделаете его более эффективным, только рисуя образцы внутри dirtyRect .

Комментарии:

1. Вы говорите, что -(void)drawRect:(NSRect)rect вызывается частично и для определенного rect элемента управления? В любом случае … поскольку [просмотр setAudioData] заставит перерисовать весь элемент управления (из-за новых волновых данных), может быть, это не так уж и важно !? или это так?

2. -(void)drawRect:(NSRect)rect вызывается по желанию Cocoa (и никогда не должен вызываться напрямую), и возможно, что потребуется перерисовать только часть представления (например, если оно находится в режиме прокрутки). В целях эффективности вам следует перерисовывать только то, что необходимо перерисовать, а не весь вид. setNeedsDisplay:YES (который должен вызываться внутри setAudioData: ) сообщает виду полностью перерисовать. Руководство по программированию Cocoa View было бы хорошим чтением.

3. о, большое вам спасибо, пока в этом нет необходимости. Если мне понадобится что-то, я обязательно свяжусь! Большое спасибо!

Ответ №2:

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

Мой план состоял бы в том, чтобы иметь NSTimer, который перемещает все столбцы волны на единицу влево каждые 0,01 секунды.

Итак, что-то вроде этого в цикле.

 for (int x; x < [WaveArray count] ; x  )
{
    UIImageView * Bar = [WaveArray ObjectAtIndex: x];
    [Bar setCenter:CGPointMake(Bar.center.x-1,Bar.center.y)];
}
 

Теперь все, что вам нужно сделать, это создать объекты правильной высоты и добавить их в WaveArray, и все они будут перемещены влево.

Комментарии:

1. Спасибо за ваш ответ. Моя проблема заключается в том, следует ли переопределять методы рисования NSView для выполнения всех упомянутых вами действий или использовать OpenGL, Quartz, просто AppKit и т. Д. Я знаком с технологией использования, но совсем не с тем, какие API использовать.

2. Я на самом деле улучшил все это с помощью контроллера представления, ха-ха.

3. У меня даже не было бы пользовательского представления

4. Хмм, мне нужно что-то более эффективное… Я думаю 🙂

5. (1) UIImageView не существует в Mac OS X, и (2) почему вы должны выполнять все отрисовки в контроллере представления вместо представления?