2016-12-22 5 views
1

Я рисую графики на NSView, используя стандартные API рисования какао. См. Изображение ниже. В NSView есть несколько графиков, которые находятся в scrollView. Каждый график имеет около 1440 точек данных, а прокрутка производительности немного борется из-за перерисовки, которая выполняется.Как оптимизировать рисование какао, чтобы обеспечить плавную прокрутку

Есть ли способ обеспечить, чтобы графика была нарисована только один раз, чтобы изображение можно было прокручивать вверх и вниз плавно?

Этот же вид используется для создания выходного файла PDF.

Учитывая, что чертеж действительно не нужно изменять, если размер не изменяется, и этого не происходит, есть ли способ предотвратить перерисовку представления во время прокрутки. Надеюсь, есть простой переключатель, чтобы убедиться, что просмотр рисуется один раз и сохраняет это в памяти !?

Базовый код находится в функции Draw() подкласса NSView.

override func draw(_ dirtyRect: NSRect) { 

    drawAxis() 

    // Only draw the graph axis during live resize 
    if self.inLiveResize { 
     return 
    } 

    plot1() 
    plot2() 
    plot3() 
    ... 

} 

func plot1(){ 

    for value in plot1Data { 

     path = NSBezierPath() 

     if isFirst { 
      path?.move(to: value) 
     } else { 
      path?.line(to: value) 
     } 
    } 
} 

enter image description here

ответ

3

Apple, имеет довольно исчерпывающие консультации в их View Programming Guide: Optimizing View Drawing статье.

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

Как описано в этой статье, вы можете часто делать еще лучше, используя методы getRectsBeingDrawn(_:count:) и/или needsToDraw(_:).

Вид прокрутки может при определенных обстоятельствах сохранить то, что уже было нарисовано, чтобы ваш вид не нужно перерисовывать. См. release notes for Responsive Scrolling. Одно из требований этого, однако, состоит в том, что ваше мнение должно быть непрозрачным. Для возврата true необходимо переопределить isOpaque. Недостаточно просто претензии быть непрозрачным. Ваш взгляд на самом деле должен быть непрозрачным, рисуя всю грязную прямую при каждом вызове до draw(). Вы можете заполнить грязный прямоугольник цветом фона перед выполнением другого чертежа, чтобы удовлетворить это требование.

Убедитесь, что для свойства изображения клика copiesOnScroll установлено значение true. Это можно сделать в IB (хотя он представлен как атрибут прокрутки, там) или в коде. По умолчанию это должно быть правдой.

Обратите внимание, что перегрузка, входящая в состав «Ревизионная прокрутка», будет происходить постепенно во время простоя. Это потребует повторных вызовов метода draw() вашего вида. Если вы не оптимизировали это, чтобы только рисовать вещи, которые пересекаются с грязными прямоугольниками, тогда эти вызовы будут медленными/дорогими. Поэтому обязательно сделайте эту оптимизацию.

+0

Хорошие предложения. Вы также можете изучить методы 'bitmapImageRepForCachingDisplayInRect:' и 'cacheDisplayInRect: toBitmapImageRep:'. Наверное, нет необходимости в этом конкретном случае, но кто знает. – bhaller

+0

Спасибо, было бы ли смысл создавать все «NSBezierPaths» только один раз, т.е. хранить их в массиве, а затем перебирать по этому массиву, чтобы проверить, пересекается ли каждый путь с грязными прямоугольниками (s), и если это так, чтобы вызвать пути Метод «stroke()»? –

 Смежные вопросы

  • Нет связанных вопросов^_^