2013-07-30 3 views
1

У меня есть очень интригующее препятствие для преодоления. Я пытаюсь отобразить живое содержимое UIView в другом, отдельном UIView.Предоставление предварительного просмотра UIView в другом UIView

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

Я пробовал множество возможных решений, и один показан here так же близко, как и я. Он работает, однако метод - (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx не вызывается при каждом изменении. Моим решением было позвонить [cloneView setNeedsDisplay] с помощью CADisplayLink, поэтому он вызывается на каждом обновлении экрана. Это очень близко к моей цели, но частота кадров крайне низкая. Я думаю, что [CALayer renderInContext:] слишком медленный.

Если возможно, что два CALayers отображают один и тот же источник, это будет золотой. Однако я не уверен, как подойти к этому. К счастью, это просто концептуальное приложение и не предназначено для App Store, поэтому я могу использовать частные API. Я просмотрел контексты IOSurface и Quartz, но до сих пор я не смог решить эту загадку. Любой вход был бы признателен!

+0

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

+0

Да, есть. Каждое представление является чрезвычайно сложным, и для дублирования требуется очень большой объем памяти и времени. Более практичным и эффективным решением было бы просто просмотреть его. OS X делает это отлично, поэтому это должно быть как-то возможно. – eswick

+0

Реализация управления миссией может использовать частные недокументированные API для OSX. API могут быть недоступны в iOS. OSX также может визуализироватьInContext со скоростью, которая намного выше на Mac, в то время как iOS выглядит лагги. –

ответ

1

iOS и OSX на самом деле в основном одинаковы внизу на самом низком уровне. (Тем не менее, когда вы поднимаетесь выше, iOS на самом деле значительно более продвинут, чем OSX, поскольку он новее и имел новый старт)

Однако в этом случае они оба используют одно и то же (я считаю). Вы заметите что-то о Mission Control. Он изолирует «окна», а не виды. В iOS каждый пользовательский интерфейс UIWindow имеет свойство «.contentID», а CALayerHost может использовать сервер рендеринга для совместного использования контекста визуализации между двумя из них (2 слоя).

Так что я советую сделать ваши представления отдельными UIWindows и получить собственное зеркальное отображение бесплатно (ish). (По моему опыту, CALayerHost берет на себя место целевых слоев с сервером рендеринга, и, если видимы CALayerHost и окно, окно больше не будет, будет только хост уровня (который, как они используются в OSX и iOS не проблема).

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

1 Вариант этого заключается в том, чтобы создать подкласс UIView, который использует https://github.com/yyfrankyy/iOS5.1-Framework-Headers/blob/master/UIKit.framework/UIView-Rendering.h#L12 этот UIView частный метод, чтобы получить IOSurface для целевой точки зрения, а затем с помощью CADisplayLink один раз в секунду получить и сделать поверхность.

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

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

What's the magic behind CAReplicatorLayer?

http://aptogo.co.uk/2011/08/no-fuss-reflections/

http://iphonedevwiki.net/index.php/SBAppContextHostManager

http://iphonedevwiki.net/index.php/SBAppContextHostView

http://iphonedevwiki.net/index.php/CALayerHost

http://iky1e.tumblr.com/post/33109276151/recreating-remote-views-ios5

http://iky1e.tumblr.com/post/14886675036/current-projects-understanding-ios-app-rendering

+0

Отлично, именно то, что я искал, просто подтолкнул в правильном направлении. У меня есть вопрос; Когда вы говорите, что каждое окно имеет свойство .contentID, вы имеете в виду свойство ._contextId? Я так полагаю. Это то, что я пробовал ранее, с CALayerHosts, однако я обнаружил, что идентификатор контекста UIWindow, являющийся подзоном другого UIWindow, имеет одинаковый идентификатор контекста. Кажется, я выяснил, почему это произошло, и я должен уметь что-то работать. Это чрезвычайно ценная информация! Вы сделали действительно потрясающую работу. – eswick

+0

UIWindows не должен быть частью других UIWindows. UIWindow - это контейнеры, которые содержат UIView, у них нет супервизора. Если вы добавляете их в другие окна, тогда да, они будут иметь тот же контекстный идентификатор, что и у их родителя, на самом деле есть один, и он просто сообщит об этом. –

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