Какао: существует ли NSView с возможностью изменения размера пользователя? - PullRequest
8 голосов
/ 10 октября 2010

Мне нужен NSView, размер которого можно изменить, перетаскивая его правый нижний угол, как NSWindow. Я хочу иметь возможность встроить этот NSView в родительский NSView. Есть ли такой компонент в Какао или его расширениях?

Ответы [ 2 ]

8 голосов
/ 10 октября 2010

Если вы уточните свой вопрос, я могу получить более конкретный ответ. : -)

Нет ничего похожего на это, о чем я знаю, но это не так уж сложно создать. Принято решение: «кто занимается рисованием ручек изменения размера и логикой изменения размера / перетаскивания?»

Представления обрабатывают свои собственные

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

Контейнерный вид Обрабатывает все подпредставления

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

Основной механизм

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

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


РЕДАКТИРОВАТЬ НА 7 ЛЕТ ПОЗЖЕ

Поскольку не было много подробностей о том, чего хотел ОП, я дал очень общий ответ, но я должен сделать несколько замечаний:

  • Всегда предпочитайте NSSplitView, если он может работать на вас (т. Е. Если представления совпадают друг с другом и разделяют пространство общего контейнера). Разделенное представление позволяет настраивать области захвата и т. Д. И делает все это для вашего подпредставления бесплатно.
  • AutoLayout не существовало, когда я написал этот ответ, и значительно усложняет развертывание вашего собственного решения для сценария view-processing-множественный-sizable-subviews.
  • Если вам действительно нужен элемент пользовательского интерфейса, который можно перетаскивать / изменять его размер в каком-либо контейнере, постарайтесь использовать CALayers внутри главного представления, которое обрабатывает всю логику макета / размеров, если вы можете.
  • Если вы не можете выполнить вышеизложенное (т. Е. Представление с изменяемым размером содержит сложные элементы управления и компоновку, имеет собственные NSViewController и т. Д.), Попробуйте гибридный подход (используйте слои для отображения кэшированных изображений невыбранных представлений). и добавьте только полное интерактивное существенное подпредставление для выбранного элемента (или подпредставления для элементов).
  • Из-за сложностей AutoLayout я действительно не могу рекомендовать реальный перетаскиваемый подход к подвиду, если только он не неизбежен. Если вы разрабатываете представление, которое содержит подвижные, значимые вещи, лучше (и наиболее эффективно) сделать все, что находится внутри него, ответственностью этого представления. Пример: графическое приложение с большим количеством фигур должно иметь представление Canvas, представляющее фигуры (и любые графические элементы оформления, такие как ручки размера / перетаскивания и т. Д.), Используя CALayers. Это использует графическое ускорение и на намного более эффективно, чем куча (очень ресурсоемких) NSView подпредставлений. Вся логика перемещения / размера / выбора обрабатывается «Canvas View», и единственными подпредставлениями могут быть наложенные элементы управления (хотя, если ваш Canvas должен быть заключен в представление с прокруткой, лучше использовать механизм NSScrollView, чтобы разрешить стационарные для этого наложенные виды).
  • Если проектируется представление, которое рисует много вещей (для которых вам определенно следует использовать слои для представления этих вещей), но позволяет выбрать только одну вещь, подход добавления подпредставления достаточно управляем даже с AutoLayout , Если «выбранная для редактирования» вещь имеет много сложных элементов управления, которые становятся видимыми при редактировании, «подпредставление редактора» с сопровождающим контроллером представления имеет смысл и является хорошим компромиссом в удобстве обслуживания (поскольку контроллер представления разделяет все функциональные возможности редактирования / обработки пользовательского интерфейса) по сравнению с . Сложность представления контейнера (поскольку одно подпредставление не нарушает банк ресурсов и поддерживает временные ограничения AutoLayout для сохранения своей позиции при изменении размеров представления контейнера и взаимодействиях редактора не слишком сложными).
  • Все это предполагает macOS; если вы разрабатываете для iOS, определенно наклоняется назад, чтобы использовать слои и новое (на момент написания) оборудование для перетаскивания, о котором я в настоящее время знаю очень мало.

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

1 голос
/ 19 сентября 2013

Вместо использования представлений вы можете использовать окна и установить маску стиля окна NSResizableWindowMask.

Другим вариантом является использование NSSplitView, если у вас есть два смежных подпредставления с изменяемым размером.

...