Допускается ли перекрытие между уровнями NSView, поддерживающими слои, и перекрытиями?
Я немного запутался. Документация Apple гласит следующее:
Примечание. По соображениям производительности Cocoa не применяет ограничение между одноуровневыми представлениями и не гарантирует правильную аннулирование и поведение при рисовании, когда одноуровневые представления перекрываются. Если вы хотите, чтобы вид был нарисован перед другим видом, вы должны сделать вид спереди подпредставлением (или потомком) вида сзади.
Таким образом, согласно этому, родственные взгляды не должны пересекаться, иначе поведение не определено.
Однако в демонстрационном приложении CocoaSlides родственные элементы NSView с дублированием слоев перекрываются, и кажется, что они работают нормально:
Так что пример кода CocoaSlides неправильный и это просто совпадение, что он работает, или документация устарела? Устарела с 10.5, то есть?
5 ответов
Перекрывающиеся виды работают нормально, на слоях или нет, на Leopard и выше.
После некоторых исследований кажется, что документация Apple действительно устарела.
Поддерживаемые на уровне уровня братья и сестры NSView могут перекрываться с 10.5.
Эта дискуссия 2009 года с участием инженеров Apple Дэвида Дункана и Корбина Данна наконец дает четкие ответы:
Пересекающиеся представления работают на Leopard, но не работают до этого. Документация устарела.
У меня есть группа представлений, каждое из которых имеет много меньших представлений внутри, которые должны быть представлены перекрывающимся способом по одному и тому же прямоугольнику в окне, чтобы их можно было видеть сквозь друг друга. В моих предварительных тестах я сделал каждый большой вид одним и тем же фоновым видом. Планировал вывести каждого на фронт, когда это было необходимо, переставив z-порядок. Есть ли будущее (или настоящее) в этом подходе?
Это будет работать на Leopard.
Источник: http://www.cocoabuilder.com/archive/cocoa/228191-nsview-behaves-different-on-10-4-vs-10-5.html
Обновление: Джеймс Демпси также ответил на Twitter:
Насколько я понимаю, перекрывающиеся друг с другом представления в порядке с 10.5, со слоями или нет.
Многослойные представления поддерживаются OpenGL (ну, в общем, Quartz compositor, но он помогает воспринимать каждый слой как многоугольник с текстурой OpenGL на нем), поэтому они всегда поддерживают правильное перекрытие.
В ветке CocoaBuilder/Cocoa-Dev слои вообще не упоминаются. Это означает, что он говорит о обычных NSViews без поддержки CALayer (или, скорее, только с CALayer для всего окна).
Одно упомянутое исключение - OpenGLView (опять же, без слоев), который всегда компоновал свой прямоугольник OpenGL в верхней части окна, стирая любые подпредставления. Я не думаю, что создание NSOpenGLView на основе слоя работает, но вместо этого можно использовать слой OpenGL, который будет правильно скомпонован между другими слоями.
Другим исключением являются слои поверх представлений без слоёв, что имеет смысл, потому что все представления без слоёв эффективно занимают один слой, который, конечно, находится ниже любого из его подуровней (в которых размещаются представления со слоями) в родительском представлении без поддержки слоя должно быть).
Короче говоря, он работает с 10.5 для неслоистых и вечно для представлений со слоями, с предостережениями при смешивании и сопоставлении или использовании OpenGL.
PS - Я не уверен на 100%, что утверждение о перекрывающихся представлениях без поддержки слоя следует воспринимать как каноническое. Это неформальное заявление инженера Apple. Все могло измениться, и могли быть обнаружены ошибки, из-за которых все не работало. Я обычно использую слои, когда я хочу правильное наложение.
Родные братья NSView, как правило, могут перекрываться. Одна вещь, которая может поразить вас, это то, как NSScrollView работает по умолчанию. Когда у вас есть ванильный NSScrollView, перекрываемый одноуровневыми представлениями, вещи ломаются.
Это из-за NSClipView, который рисует только ту часть прокручиваемого представления и копирует то, что не изменилось. Если у вас есть одноуровневые представления, которые перекрывают представление прокрутки, эта оптимизация не работает, и представления, кажется, прокручиваются, даже если они только одноуровневые.
Для того чтобы перекрывающиеся одноуровневые представления работали, даже если они не имеют слой-основы, вам необходимо отключить эту оптимизацию:
[scrollView.contentView setCopiesOnScroll:NO];
Это может быть полезно для кого-то: у меня возникла проблема с мерцающим перекрывающимся неуровневым подпредставлением в MacOS 10.7+. В моем приложении представления использовались для визуализации некоторой информации о выбранном графическом объекте (рамка выбора, масштабирование контрольных точек и т. Д.), Поэтому у них была некоторая анимация - вот они и являются ключевыми в моем случае.
Кажется, что перекрывающиеся братья и сестры действительно отлично работают даже без слоя, но в более простых случаях. У меня была куча анимированных просмотров, каждый со своим таймером - и он щелкнул. Я нашел два решения: либо включить слои, либо синхронизировать анимацию, переключиться на один общий таймер и обновить все виды одновременно.
По крайней мере, этот трюк помог в моем приложении, так как я не хотел использовать слои.