Вопрос по core-animation, cocoa, nsview, calayer – Допускается ли перекрытие между уровнями NSView, поддерживающими слои, и перекрытие?

11

Я немного сбит с толку. Документация Apple утверждает это:

Note: For performance reasons, Cocoa does not enforce clipping among sibling views or guarantee correct invalidation and drawing behavior when sibling views overlap. If you want a view to be drawn in front of another view, you should make the front view a subview (or descendant) of the rear view.

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

вКакао слайды демонстрационное приложениеТем не менее, слой с поддержкой NSView братьев и сестерdo overlap и вроде работает просто отлично

Cocoa Slides screenshot

Так что пример кода Cocoa Slides неверен и это просто совпадение того, что он работает, или документация устарела? Устарел с 10,5, то есть?

Ваш Ответ

5   ответов
1

как правило, могут перекрываться. Одна вещь, которая может поразить вас, это то, как NSScrollView работает по умолчанию. Когда у вас есть ванильный NSScrollView, перекрываемый одноуровневыми представлениями, вещи ломаются.

Это происходит из-за NSClipView, который рисует только ту часть прокручиваемого представления и копирует материал, который не изменился. Когда у вас есть одноуровневые представления, которые перекрывают представление прокрутки, эта оптимизация не работает, и представления, кажется, прокручиваются, даже если они являются только одноуровневыми элементами.

Чтобы заставить перекрывающиеся одноуровневые представления работать, даже если они не имеют слой-основы, вам необходимо отключить эту оптимизацию:

[scrollView.contentView setCopiesOnScroll:NO];
Вы, сэр, джентльмен и ученый. Johannes Fahrenkrug
7

что документация Apple действительно устарела.

Layer-backed NSView siblings are allowed to overlap since 10.5.

этообсуждение с 2009 годас участием инженеров Apple Дэвида Дункана иКорбин Данн наконец, дает несколько четких ответов:

Overlapping views work on Leopard, but do not work before that. The documentation is out of date.

I have a group of views, each one with many smaller views inside, which need to be presented in an overlapping manner over the same rect on a window, so that they can be seen through each other. In my preliminary tests, I made each big view a sibling of a single background view. Was planning on bringing each one to the front, when necessary by re-arranging the z-order. Is there any future (or present) in this appoach?

That will work on Leopard.

Источник:http://www.cocoabuilder.com/archive/cocoa/228191-nsview-behaves-different-on-10-4-vs-10-5.html#228983

Update: The Джеймс Демпси также ответил на Twitter:

My understanding is that overlapping sibling views are OK as of 10.5, layer-backed or not.

@nschmidt Интересно. Возможно, у вас есть пример приложения, которое показывает, что проблематично иметь перекрывающиеся одноуровневые NSViews без резервной копии? Два (бывших) инженера Apple говорят, что это нормально с 10.5, и в моих тестах это было похоже на правду. Johannes Fahrenkrug
@nschmidt Отлично, спасибо. По моему опыту, NSScrollView, похоже, сам по себе чудовище. NSScrollView имеет целую внутреннюю иерархию представлений, и он действительно не очень хорошо работает с перекрывающимися одноуровневыми представлениями, когда они не поддерживаются на уровне слоев. Другие, не такие сложные, взгляды просто перекрываются. Johannes Fahrenkrug
Я загрузил простую демонстрацию вgithub, На заднем плане вид прокрутки, перекрытый парой видов. Когда вы прокручиваете, все запутано.
Близким слоям NSView без слоя не разрешается перекрываться. Смотри мой ответ.
4

в общем, Quartz compositor, но он помогает воспринимать каждый слой как многоугольник с текстурой OpenGL на нем), поэтому они всегда поддерживают правильное перекрытие.

Поток на CocoaBuilder / Cocoa-Dev вообще не упоминает слои. Это означает, что речь идет о обычных NSViews без поддержки CALayer (точнее, только с CALayer для всего окна).

Одним из упомянутых исключений является OpenGLView (опять же, без слоев), который всегда компонует свой прямоугольник OpenGL в верхней части окна, стирая любые подпредставления. Я не думаю, что создание слоя с поддержкой NSOpenGLView работает, но вместо этого можно использовать слой OpenGL, который будет правильно скомпонован между другими слоями.

Другим исключением являются слои поверх представлений без слоёв, что имеет смысл, потому что все представления без слоёв эффективно занимают один слой, который, конечно, находится ниже любого из его подуровней (в которых размещаются представления со слоями) в родительском представлении без поддержки слоя должно быть).

Короче говоря, он работает с 10.5 для неслоистых и вечно для представлений со слоями, с предостережениями при смешивании и сопоставлении или использовании OpenGL.

PS - Я не уверен на 100%, что утверждение о перекрывающихся представлениях без поддержки слоя следует воспринимать как каноническое. Это неофициальное заявление инженера Apple. Все могло измениться, и могли быть обнаружены ошибки, из-за которых все не работало. Я обычно использую слои, когда я хочу правильное наложение.

Я нигде не говорю, что перекрытие работает с представлениями без слоя. Это определенно сделалnot работать в старых версиях (хотя обычно это выглядело так, как будто работало, в случайных случаях оно ломалось, что-то очень недетерминированное в перекрывающихся представлениях без слоя)
Интересно! Я даже не заметил, что они явно не упоминали слои. Тем не менее, Core Animation существует только с 10.5, поэтому до этого не было ни одного слоя с поддержкой слоев. Вы уверены, что перекрытие надежно работает с представлениями без слоев? Это первый раз, когда я слышу это (было бы здорово, хотя!). Это также может быть актуально:stackoverflow.com/questions/466297/… Johannes Fahrenkrug
О, кажется, я действительно сказал, что это работает с 10.5 для неслоистых. : -S
2

у меня возникла проблема с мерцающим перекрывающимся неуровневым подпредставлением в MacOS 10.7+. В моем приложении представления использовались для визуализации некоторой информации о выбранном графическом объекте (рамка выделения, контрольные точки масштабирования и т. Д.), Поэтому они имели некоторыеanimation - это ключ к моему делу.

,

Кажется, что перекрывающиеся братья и сестры действительно работают хорошо даже без слоя, но в более простых случаях. У меня было несколько анимированных представлений, каждое со своим таймером - и оно щелкнуло. Я нашел два решения: либо включитьlayers или жеsynchronize the animationпереключение на один общий таймер и обновление всех видов одновременно.

По крайней мере, этот трюк помог в моем приложении, так как я не хотел использовать слои.

9

на слоях или нет, на Leopard и выше.

Ули, это цитата :)
{нужна цитата}
Мои наблюдения по этой теме совпадают с ответом @uliwitness. Существуют предостережения, когда вы смешиваете и сопоставляете представления с слоями и без слоев.
К сожалению, они не работают, если они не наслоены. Я пытаюсь сделать дыру в окне CEF (Chrome Chrome Chrome) с помощью дополнительного NSView, чтобы он не отображался после него. (кажется, CEF внутренне использует OpenGL или другую магию). Единственный способ, который я нашел, - это сделать мой NSView многоуровневым и оставить этот CEF обычным.

Похожие вопросы