2015-04-10 2 views
1

Я пытаюсь создать иерархию вид, похожий на то, что вы ожидали бы в средстве просмотра воспроизведения медиа как в QuickTime Player:Использование AVPlayerLayer в качестве основы для слоя с NSView

+ Host View 
    + Video Controls (NSView layer-backed) 
    + Video View (NSView layer-hosted) 
    + AVPlayerLayer 

Поскольку слой организовали представления не могут содержать subviews, представление управления видео - это вид видеоизображения и просто упорядоченный фронт, так что он находится поверх видеоизображения.

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

Этот вопрос о переполнении стека: Is there a proper way to handle overlapping NSView siblings? предлагает противоречивую информацию о перекрывающихся взглядах братьев и сестер.

Я бы предположил, что более «правильный» способ справиться с этим заключается в том, что элементы управления видео являются подчиненными для просмотра видео, что возможно только из того, что я изменяю вид видео из того, что вы представляете собой слой, - просмотренный вид.

По умолчанию вид слоя спинок использует базовую CALayer в качестве своего резервного хранилища, но NSView выставляет makeBackingLayer, чтобы позволить вам вернуться пользовательским слой, такие как AVPlayerLayer.

Таким образом, и перемещение вида элементов управления является подвидным видом видеоизображения с поддержкой слоя, все также работает правильно, но теперь есть объект AVPlayer, который непосредственно изменяет содержимое AVPlayerLayer. Это противоречит требованию, что в режиме с поддержкой слоя вы никогда не должны изменять содержимое слоя, не проходя через NSView, используя что-то вроде drawRect или updateLayer.

Это, кажется, оставляет меня два варианта, ни один из которых появляется «правильного» на основе моей интерпретации документа:

Вариант 1:

  • Layer организовали просмотр для AVPlayerLayer
  • Перекрывая вид сестры для просмотра элементов управления.

Вариант 2:

  • вид Слой-назад с AVPlayerLayer через makeBackingLayer
  • AVPlayer, который непосредственно изменяет содержимое управляет AVPlayerLayer
  • посмотреть как подвид окна просмотра видео

Я склонен думать, что вариант № 2 является более правильным способом, и что в этом сценарии нормально для AVPlayer прямо изменить содержимое AVPlayerLayer, даже если оно находится в режиме с поддержкой слоя, но я не определенно и было бы любопытно, если бы у других были какие-то мысли или опыт с такой установкой.

ответ

1

Apple имеет несколько старых (древних в компьютерных терминах, 2007!), который даже не компилируется в Xcode 6 без каких-либо настроек. Он показывает некоторые элементы управления, которые накладываются на слой QuickTime. Загрузите его здесь: https://developer.apple.com/library/mac/samplecode/CoreAnimationQuickTimeLayer/Introduction/Intro.html.

Трудно сказать, что только потому, что они предоставили исходный код, что это считается лучшей практикой, но я бы предложил вам просто построить его так, как вы считаете лучшим. Это не одна из тех областей, которые так сильно развиты, что лучшая практика, вероятно, будет существовать. Для меня лично имеет смысл использовать совпадающие представления для сестер, чтобы убедиться, что вы не возитесь с рендерингом видео. Правильно ли это или нет, возможно, несколько субъективно. Вы можете получить доступ к одному из старых списков рассылки разработчиков quicktime или даже спросить на форумах разработчиков Apple. В конце дня, хотя вы, вероятно, должны просто придерживаться метода, который имеет для вас наибольший смысл, поскольку вы, скорее всего, будете поддерживать или развивать его в будущем.

+0

Интересно, что в образце кода они, кажется, добавляют подсловы к виду с поддержкой слоя, что, насколько мне известно, никогда не было «правильным». В конце концов, я решил использовать 'makeBackingLayer', потому что если вы не можете установить уровень поддержки NSView для чего-то другого, кроме универсального' CALayer', то в чем смысл 'makeBackingLayer'? Вы могли бы просто использовать представление, размещенное на уровне, а затем для вашего пользовательского 'CALayer', а представления, размещенные на уровне слоев, определенно документированы как не поддерживающие subviews. Кажется, что все работает ... Спасибо за вход. – kennyc