Какао автоматическая информация о версии расположения

Содержание:

О какао автоматическое расположение

OS X Lion представляет новую систему расположения для Какао, заменяя историческую модель пружин и распорок. Вместо того, чтобы использовать маски автокалибровки, Вы определяете ограничения макета, выражающие Ваше намерение, такое как “эти представления выстраивают в линию голову к хвосту”, или “эта кнопка должна переместиться с этим подпредставлением представления разделения”.

Иллюстрация, 1-1Laying метка image: Art/tramStop.png

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

Новый подход должен сохранить руководства по пунктирной линии от Интерфейсного Разработчика вместо просто кадров представлений. Вместо того, чтобы быть одноразовыми помощниками для установки кадра в файле пера, руководства становятся персистентными объектами первого класса, названными ограничениями. Ограничительный экспресс желал отношений между элементами пользовательского интерфейса. При разметке пользовательского интерфейса ограничительная система удовлетворенности располагает элементы в пути, наиболее близко встречающем ограничения.

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

Существуют также более тонкие преимущества:

Ограничительные явно выраженные отношения между представлениями

Единственный новый класс NSLayoutConstraint, экземпляры которого представляют ограничения. Ограничение является оператором формы

y = m*x + b

Следующее представляет конкретный пример ограничения (несмотря на то, что оно представлено как псевдокод):

button1.right == button2.left - 12.0

Ограничение также имеет дополнительный приоритетный уровень с плавающей точкой. Ограничения с более высокими приоритетными уровнями удовлетворены перед ограничениями с более низкими приоритетными уровнями. Приоритетный уровень по умолчанию NSLayoutPriorityRequired, что означает, что ограничение должно быть удовлетворено точно. Система расположения стремится встретить дополнительное ограничение, даже если она не может полностью достигнуть его. Если ограничение a == b является дополнительным, это означает это abs(a - b) должен быть минимизирован.

Приоритетные уровни позволяют Вам выражать полезное условное поведение. Например, они используются для выражения, что все средства управления должны всегда измеряться для адаптации их содержанию, если что-то более важное не предотвращает его. Для большего количества подробности об этом примере посмотрите Делящуюся Ответственность Между Контроллерами и Представлениями.

Ограничения, с некоторыми ограничениями, могут пересечь иерархию представления. В Почте, например, по умолчанию кнопка Delete на панели инструментов выстраивается в линию с таблицей сообщений, и в Настольных Предпочтениях, флажки у основания окна выравниваются с областью просмотра разделения, на которую они воздействуют.

image: Art/desktopPrefs.png

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

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

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

Создайте ограничения программно Используя визуальный язык формата

Исходный код традиционно не передает визуальное представление хорошо

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

   if (_accessoryView) {
        minYMessageAndAccessories -= [_accessoryView frame].size.height;
        if ([self showsSuppressionButton]) {
            // we’ve already accounted for the spacing above the suppression button and below the accessory view.  Add spacing between.
            minYMessageAndAccessories -= ACCESSORY_INTERY_SPACING;
            // adjust y-origin of suppression button since there is also an accessory view
            NSPoint buttonOrigin = [_suppressionButton frame].origin;
            buttonOrigin.y += [_accessoryView frame].size.height + ACCESSORY_INTERY_SPACING;
            [_suppressionButton setFrameOrigin:buttonOrigin];
        } else {
            // we need spacing above and below accessory view
            minYMessageAndAccessories -= ACCESSORY_MINY_SPACING + ACCESSORY_MAXY_SPACING;
        }
    }
 
    if (_imageView != nil) {
        if (minYMessageAndAccessories < NSMinY([_imageView frame])) {
            panelHeight += NSMinY([_imageView frame]) - minYMessageAndAccessories;
        }
    }

Возможно невозможно понять сразу, что делает этот код. Также трудно поддержать — изменение поведения расположения будет хитро и подвержено ошибкам. На практике эта ситуация менее распространена, чем мог бы иметь место, потому что вместо того, чтобы писать такой код, Вы используете Интерфейсного Разработчика:

image: Art/alertPanel.png

Это - основной элемент подхода к удобству пользования: необходимо быть в состоянии визуализировать расположение. Самый большой компонент для этого является Интерфейсным Разработчиком. Однако также желательно визуализировать расположение в коде также. Рассмотрите расположение этих кнопок:

image: Art/twoButtons.png

Левая сторона button2 стандартное пространство Воды далеко от правой стороны button1. Для простоты иллюстрации, замена “стандартный интервал Воды” с простой константой, 12. Используя основной метод для ограничительного создания, Вы могли бы создать ограничение как это:

[NSLayoutConstraint constraintWithItem:button1
                    attribute:NSLayoutAttributeRight
                    relatedBy:NSLayoutRelationEqual
                    toItem:button2
                    attribute:NSLayoutAttributeLeft
                    multiplier:1.0
                    constant:-12.0];

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

Какао автоматическое расположение предлагает визуальное представление расположения в исходном коде

Для обеспечения визуального представления в исходном коде Какао, Автоматическое Расположение представляет ВДОХНОВЛЕННУЮ ASCII-ТВОРЧЕСТВОМ строку формата. Представление представлено в квадратных скобках, и соединение между представлениями представлено с помощью дефиса. Таким образом отношение между button1 и button2 может быть представлен как:

[button1]-12-[button2]

Или, так как это - стандартное пространство Воды, просто:

[button1]-[button2]

Для создания ограничений визуально Вы используете constraintsWithVisualFormat:options:metrics:views:. Вы указываете представления с помощью views словарь — ключи являются именами, которые Вы используете в строке формата, и значения являются соответствующими представлениями. Код для создания ограничений таким образом становится:

NSDictionary *views = NSDictionaryOfVariableBindings(button1, button2);
NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"[button1]-[button2]"
                                           options:0
                                           metrics:nil
                                           views:views];

Визуальный синтаксис формата

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

Стандартное пространство

[button]-[textField]

image: Art/standardSpace.png
Ограничение ширины

[button(>=50)]

image: Art/widthConstraint.png
Соединение с суперпредставлением

|-50-[orchidBox]-50-|

image: Art/connectionToSuperview.png
Вертикальный макет

V:[topField]-10-[bottomField]

image: Art/verticalLayout.png
Представления сброса

[maroonView][oceanView]

image: Art/flushViews.png
Приоритет

[button(100@20)]

image: Art/priority.png
Равные ширины

[button1(==button2)]

image: Art/equalWidths.png
Многократные предикаты

[flexibleButton(>=70,<=100)]

image: Art/multiplePredicates.png
Полная строка расположения

|-[find]-[findNext]-[findField(>=20)]-|

image: Art/completeLayout.png

Нотация предпочитает хорошую визуализацию по полноте expressibility. Несмотря на то, что некоторые ограничения не могут быть выражены в визуальном синтаксисе формата, большинство, которые находятся в интерфейсах реального пользователя, может быть. Одно полезное ограничение, которое не может быть выражено, является фиксированным форматным соотношением (например, imageView.width = 2 * imageView.height). Для создания такого ограничения необходимо использовать основной метод создания.

Визуальная грамматика строки формата

Визуальная грамматика строки формата определяется следующим образом (литералы показаны в code font; e обозначает пустую строку).

Символ

Заменяющие правила

<visualFormatString>

(<ориентация> :)? (<суперпредставление> <соединение>)? <представление> (<соединение> <представление>) * (<соединение> <суперпредставление>)?

<ориентация>

H|V

<суперпредставление>

|

<представление>

[<viewName> (<predicateListWithParens>)?]

<соединение>

e |-<predicateList>-|-

<predicateList>

<simplePredicate> | <predicateListWithParens>

<simplePredicate>

<metricName> | <positiveNumber>

<predicateListWithParens>

(<предикат> (,<предикат>) *)

<предикат>

(<отношение>)? (<objectOfPredicate>) (@<приоритет>)?

<отношение>

==|<=|>=

<objectOfPredicate>

<постоянный> | <viewName> (см. примечание),

<приоритет>

<metricName> | <число>

<постоянный>

<metricName> | <число>

<viewName>

Проанализированный как идентификатор C.

Это должно быть ключом, отображающимся на экземпляр NSView в переданном словаре представлений.

<metricName>

Проанализированный как идентификатор C.

Это должно быть ключом, отображающимся на экземпляр NSNumber в переданном метрическом словаре.

<число>

Как проанализировано strtod_l, с локалью C.

Если Вы делаете синтаксическую ошибку, исключение выдается с сообщением диагностики. Например:

Expected ':' after 'V' to specify vertical arrangement
V|[backgroundBox]|
 ^
 
A predicate on a view's thickness must end with ')' and the view must end with ']'
|[whiteBox1][blackBox4(blackWidth][redBox]|
                                 ^
 
Unable to find view with name blackBox
|[whiteBox2][blackBox]
                     ^
 
Unknown relation. Must be ==, >=, or <=
V:|[blackBox4(>30)]|
               ^

Добавьте ограничения к представлениям

Для создания ограничения активным необходимо добавить его к представлению. Представление, содержащее ограничение, должно быть наследователем представлений, которые ограничение включает, часто самый близкий общий предок. (Это находится в существующем NSView Наследователь значения слова API, где представление является наследователем себя.) Ограничение интерпретируется в системе координат того представления.

Предположим, что Вы устанавливаете [zoomableView1]-80-[zoomableView2] на общем предке zoomableView1 и zoomableView2.

image: Art/helloHi-1.png

Эти 80 находятся в системе координат контейнера, который является тем, на что это похоже, визуализируете ли Вы ограничение.

Если границы преобразовывают любого из zoomable изменений представлений, пространство между ними остается фиксированным.

image: Art/helloHi-2.png

Если границы преобразовывают в сам контейнер, изменяется, то пространство масштабируется, также.

image: Art/helloHi-3.png

NSView обеспечивает метод —addConstraint:— добавить ограничение и методы, чтобы удалить или проверить существующие ограничения —removeConstraint: и constraints— а также другие связанные методы. NSView также обеспечивает метод, fittingSize, который подобен sizeToFit метод NSControl но для произвольных представлений, а не для средств управления.

fittingSize метод возвращает идеальный размер для представления, считая только те ограничения установленными на поддереве получателя вместе с предпочтением представления, чтобы быть как можно меньше. Подходящий размер не является «лучшим» размером для представления в общем смысле — в системе на основе ограничений, «лучший» размер представления, если Вы полагаете, что все должно быть размером, который это в настоящее время имеет!

Базовое время выполнения расположения

В дополнение к Какао передачи «дисплея» всегда использовал, Какао, Автоматическое Расположение добавляет еще две передачи, происходящие при рендеринге окна: updateConstraintsIfNeeded и layoutIfNeeded. Они происходят в порядке: ограничения Обновления, разметьте, дисплей. Если Вы вызываете display вручную, это вызывает layout и layout вызывает updateConstraints.

Можно думать об ограничительной передаче обновления как об измерительной передаче, передающей изменения в геометрии к системе расположения. Например, при изменении заголовка кнопки в некоторый момент, текст должен быть измерен, и ограничение должно быть установлено, который передает ту информацию в систему расположения. Ограничительная передача обновления снизу вверх.

Именно в передаче расположения кадры представлений обновляются. Передача расположения является нисходящей.

Эти передачи имеют параллельные наборы методов:

Дисплей

Расположение

Ограничения обновления

Переопределение

Вызовите Directly

Выполните передачу на уровне окна

displayIfNeeded

(NSWindow)

layoutIfNeeded

(NSWindow)

updateConstraintsIfNeeded

(NSWindow)

Нет.

Если Вам нужны вещи быть актуальными прямо сейчас, обычно вызванный автоматически AppKit, но может быть вызван.

Выполните передачу на уровне представления

Устанавливает вещи и вызывает представление переопределяемый метод на все представления в поддереве, которые грязны относительно передачи.

displayIfNeeded

(NSView)

layoutSubtreeIfNeeded

(NSView)

updateConstraintsForSubtreeIfNeeded

(NSView)

Нет.

Если Вам нужны вещи быть актуальными прямо сейчас, обычно вызванный автоматически AppKit, но может быть вызван.

Уровень представления переопределяемый метод

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

drawRect:

(NSView)

layout

(NSView)

updateConstraints

(NSView)

Да.

Вы не должны вызывать эти методы непосредственно.

Аннулирование

Доберитесь / методы установки для аннулирования передачи.

needsDisplay (NSView)

setNeedsDisplay: (NSView)

needsLayout (NSView)

setNeedsLayout: (NSView)

needsUpdateConstraints

(NSView)

setNeedsUpdateConstraints:

(NSView)

Нет.

Да, если/когда необходимо.

При реализации пользовательского представления наиболее распространенные методы для взаимодействия с являются уровнем представления переопределяемые методы и методы аннулирования.

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

Объект контроллера обычно более касается в NSWindow и NSView методы, выполняющие передачу. Это использование более редко, хотя все еще допустимый и необходимый при случае.

Деление ответственности между контроллерами и представлениями

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

Некоторые представления имеют внутренний размер содержания

Представления уровня листа, такие как кнопки обычно знают больше, о каком размере они должны быть, чем делает код, располагающий их. Размер такого представления, гарантирующего его содержание, выведен на экран, соответственно его внутренний размер. Не все представления имеют внутренний размер содержания. Автоматическая система Расположения вызывает представление intrinsicContentSize метод, чтобы узнать, указывает ли представление, как большой это хотело бы быть. Представление может возвратить абсолютные значения для своей ширины и высоты, или NSViewNoInstrinsicMetric или для или для оба, чтобы указать, что это не имеет никакого предпочтения данной размерности.

Например, внутренний размер для кнопки диктуют ее заголовок и изображение. Кнопка intrinsicContentSize метод должен возвратить размер, ширина которого и высота гарантируют, что текст заголовка не отсекается и что целое изображение видимо. Горизонтальный ползунок, однако, имеет внутреннюю высоту, но никакая внутренняя ширина — иллюстрации ползунка не имеют никакой внутренней лучшей ширины. Горизонталь NSSlider объектные возвраты {NSViewNoInstrinsicMetric, <slider height>}. Текстовая метка возвращает значение, указывающее стандартную высоту, данную шрифт, используемый, и гарантирующая ширина, текст не будет отсечен. Контейнер, такой как экземпляр NSBox, также не имеет никакого внутреннего размера содержания и возвратов { NSViewNoInstrinsicMetric, NSViewNoInstrinsicMetric }. Его подпредставления могут иметь внутренние размеры содержания, но содержание подпредставлений не является внутренним самому полю.

Если представление реализует intrinsicContentSize метод, Автоматическая система Расположения устанавливает ограничения, указывающие (1), что непрозрачное содержание не должно быть сжато или отсечено, (2), который представление предпочитает обнимать плотно к его содержанию.

Можно указать, насколько важный внутренний размер

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

  • Это строго хочет обнять свое содержание в вертикальном направлении (кнопки действительно должны быть своей естественной высотой),

  • Это слабо обнимает свое содержание горизонтально (дополнительное дополнение стороны между заголовком, и край внешней панели приемлем),

  • Это строго сопротивляется сжатию или отсечению содержания в обоих направлениях

В панели объема в Средстве поиска, однако, кнопки только слабо сопротивляются сжимающемуся содержанию в горизонтальном направлении. (Можно сделать окно достаточно маленьким, что кнопки начинают усекать свое содержание.) Таким образом Средство поиска должно понизить приоритет, с которым эти кнопки сопротивляются сжимающемуся содержанию. Вы устанавливаете приоритеты объятия и сжатия для использования представления setContentHuggingPriority:forOrientation: и setContentCompressionResistancePriority:forOrientation: соответственно. По умолчанию представление имеет значение также NSLayoutPriorityDefaultHigh или NSLayoutPriorityDefaultLow.

Если их внутренний размер изменяется, представления должны сказать автоматическую систему расположения

Несмотря на то, что Автоматическая архитектура Расположения сокращает нагрузку на лице, осуществляющем внедрение класса контроллера, Автоматическое Расположение может немного увеличить нагрузку на лице, осуществляющем внедрение класса представления. При реализации пользовательского класса представления необходимо определить, имеет ли представление внутренний размер и, если так, реализация intrinsicContentSize возвратить подходящее значение.

Кроме того, если свойство представления изменяется, и то изменение влияет на внутренний размер содержания, представление должно вызвать invalidateIntrinsicContentSize так, чтобы система расположения заметила изменение, и может перерасположение. В реализации Вашего класса представления необходимо гарантировать что, если значение свойства, от которого внутренний размер зависит изменения, Вы вызываете invalidateIntrinsicContentSize. Например, текстовое поле вызывает invalidateIntrinsicContentSize если изменяется строковое значение.

Расположение воздействует на прямоугольники выравнивания, не кадры

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

В следующем примере руководство по Воде (штриховая синяя строка) выравнивается с визуальной степенью кнопки, не с кадром кнопки (существенный синий прямоугольник).

image: Art/buttonGuideFrame.png

Для разрешения расположения на основе представления содержания, а не кадра представления обеспечивают alignmentRect объект, который является тем, на что фактически воздействует расположение.

Представления могут указать базовые смещения

Часто Вы хотите выровнять средства управления базовой линией. Несмотря на то, что Вы всегда были в состоянии сделать это в Интерфейсном Разработчике, не было ранее возможно сделать это во время выполнения. Можно сделать так теперь использование NSLayoutAttributeBaseline в ограничении.

Метод baselineOffsetFromBottom возвращает расстояние между NSLayoutAttributeBottom и NSLayoutAttributeBaseline. Это возвращаемое значение по умолчанию для NSView 0; метод переопределяется подклассами, для которых он целесообразен делать так.

Отладка

В автоматической системе расположения возможность отладить эффективно ясно очень важна. Какао Автоматическое Расположение предлагает несколько функций, чтобы помочь Вам найти источник ошибок. Вы цель в отладке состоит в том, чтобы обычно идентифицировать неправильное или неправильно прикладной, ограничиваете следующим этот процесс:

  1. Идентифицируйте проблему.

    Например, заметьте, что представление находится в неправильном месте.

  2. Если возможно, воспроизведите проблему при выполнении под новым шаблоном «расположения» в Инструментах.

    (Это может быть включено с инструментами разработчика в будущем, но в настоящее время предоставлено в связанном примере кода — посмотрите Пример кода).

  3. Найдите плохое ограничение или ограничения.

    Для получения ограничений, влияющих на определенное представление, использовать constraintsAffectingLayoutForOrientation:. Можно тогда проверить ограничения в отладчике. Они распечатаны с помощью визуальной нотации формата. Если Ваши представления имеют идентификаторы (см. identifier (NSView)), они распечатывают использование идентификатора в описании, как это:

    <NSLayoutConstraint: 0x400bef8e0 H:[refreshSegmentedControl]-(8)-[selectViewSegmentedControl] (Names: refreshSegmentedControl:0x40048a600, selectViewSegmentedControl:0x400487cc0 ) >

    Иначе, вывод похож на это:

    <NSLayoutConstraint: 0x400cbf1c0 H:[NSSegmentedControl:0x40048a600]-(8)-[NSSegmentedControl:0x400487cc0]>

    Если это не очевидно, какое ограничение является неправильным в этой точке, визуализируйте ограничения на экран путем передачи ограничений использованию окна visualizeConstraints:. Рисунок 1-2 показывает пример визуализации ограничений, влияющих на горизонтальный макет поля находки.

    Полагайте, что 1-2Constraint окно отладки вывело на экран использование visualizeConstraints:. image: Art/findPanelVisualization.png

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

  4. Найдите код, это неправильно.

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

    Если дело обстоит не так, то в Инструментах ищут указатель ограничения (или часть его описания). Это покажет Вам интересные события в жизненном цикле того ограничения — его создание, модификация, установка в окна, и т.д. Для каждого из них Вы видите след, где это произошло. Найдите этап, на котором спутались вещи, и смотрите на след. Это - код с проблемой.

Неоднозначность

На рисунке 1-2 Вы, возможно, заметили, что отчет “Расположение не неоднозначен”. Расположение неоднозначно, если это - underspecified. Например, предположите, что система состоит из одного ограничения.

x + y == 100

Поскольку существует бесконечное число решений этого уравнения, система неоднозначна (в противоположность невыполнимому). Можно разрешить его путем добавления второго ограничения, такого как:

x == y

В нормальном ходе решения расположения система обнаруживает невыполнимость, но не неоднозначность. (Это по причинам производительности — это - в вычислительном отношении дорогая задача обнаружить неоднозначность в этой системе.) Однако при визуализации ограничений система действительно проверяет на неоднозначность. Если это обнаруживает неоднозначность, visualizer представляет кнопку Exercise Ambiguity. Рисунок 1-3 показывает панель находки после того, как было удалено одно из ограничений.

Изобразите 1-3Constraint неоднозначность иллюстрирования окна отладки image: Art/ambiguity1.png

Осуществление неоднозначности (нажимающий кнопку) заставляет Ваш UI переключиться между различными состояниями, что это могло быть в учитывая текущий набор ограничений. Рисунок 1-4 показывает расположение панели находки после щелчка по Exercise Ambiguity. Заметьте различное расположение.

Изобразите 1-4Constraint окно отладки, иллюстрирующее альтернативное разрешение неоднозначности image: Art/ambiguity2.png

Выборка FindPanelLayout идет через этот пример отладки, а также демонстрацию других проблем.

Невыполнимость

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

  1. addConstraint: метод (или setConstant: метод NSLayoutConstraint) регистрирует взаимно невыполнимые ограничения и выдает исключение.

    Исключение является надлежащим, так как это - ошибка программиста.

  2. Система сразу ловит исключение.

    Несмотря на то, что добавление ограничения, которое не может быть удовлетворено, является ошибкой программиста, это - то, которое может с готовностью быть предсказано, произойдя на компьютере пользователя, и один, с которого система может восстановиться более корректно, чем это может путем катастрофического отказа программы. Исключение выдается так, чтобы Вы заметили проблему — и пойманный, потому что проще отладить ограничительную систему, если все еще функционирует система.

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

2010-08-30 03:48:18.589 ak_runner[22206:110b] Unable to simultaneously satisfy constraints:
(
  "<NSLayoutConstraint: 0x40082d820 H:[NSButton:0x4004ea720'OK']-(20)-|  (Names: '|':NSView:0x4004ea9a0 ) >",
  "<NSLayoutConstraint: 0x400821b40 H:[NSButton:0x4004ea720'OK']-(29)-|  (Names: '|':NSView:0x4004ea9a0 ) >"
)
 
Will attempt to recover by breaking constraint
<NSLayoutConstraint: 0x40082d820 H:[NSButton:0x4004ea720'OK']-(20)-|  (Names: '|':NSView:0x4004ea9a0 ) >

Автоматическое расположение поддерживает инкрементное принятие

Представления, знающие об Автоматическом Расположении, могут сосуществовать в окне с представлениями, которые не являются. Т.е. существующий проект может инкрементно принять функции Auto Layout.

Это работает через свойство translatesAutoresizingMaskIntoConstraints. Когда значение этого свойства YEStrue, который это по умолчанию, маска автоизменения размеров представления переводится в ограничения. Например, если представление сконфигурировано как на рисунке 1-5 и translatesAutoresizingMaskIntoConstraints YEStrue, тогда ограничения |-20-[button]-20-| и V:|-20-[button(20)] добавляются к суперпредставлению представления. Результирующий эффект состоит в том, что не сознающие представления ведут себя, как они сделали в версиях OS X ранее, чем версия 10.7.

Изобразите 1-5Button расположение, использующее пружины и распорки image: ../Art/springsAndStruts.png

Если Вы перемещаете точки кнопки 15 налево (включая путем вызова setFrame: во время выполнения), новые ограничения были бы |-5-[button]-35-| и V:|-20-[button(20)].

Для представлений, знающих об Автоматическом Расположении при большинстве обстоятельств, которые Вы захотите translatesAutoresizingMaskIntoConstraints быть NOfalse. Это вызвано тем, что ограничения, сгенерированные путем перевода маски автоизменения размеров, уже достаточны для завершенного указания кадра мнения, высказанного кадр его суперпредставления, который является обычно слишком много. Например, когда ее заголовок будет изменен, это предотвратит кнопку от автоматического принятия ее оптимальной ширины.

Основное обстоятельство, при котором Вы не должны вызывать setTranslatesAutoresizingMaskIntoConstraints: когда Вы не лицо, указывающее отношение представления к его контейнеру. Например, NSTableRowView экземпляр помещается NSTableView. Это могло бы сделать это, позволив маске автоизменения размеров быть переведенным в ограничения, или это не могло бы. Это - частная подробность реализации. Другие представления, на которых Вы не должны вызывать setTranslatesAutoresizingMaskIntoConstraints: включать NSTableCellView, подпредставление NSSplitView, NSTabViewItem представление или представление содержания NSPopover, NSWindow, или NSBox. Для знакомых с классическим расположением Какао: Если Вы не вызвали бы setAutoresizingMask: на представлении в классическом стиле Вы не должны вызывать setTranslatesAutoresizingMaskIntoConstraints: в автоматическом расположении.

Если у Вас есть представление, делающее его собственное расположение путем вызова setFrame:, Ваш существующий код должен работать. Просто не вызывайте setTranslatesAutoresizingMaskIntoConstraints: с параметром NOfalse на представлениях, что Вы помещаете вручную.

Для обеспечения дополнительной совместимости вся система расположения на основе ограничений неактивна, пока Вы не устанавливаете ограничение на представление. Как правило, это не что-то, что Вы должны быть обеспокоены в, но если Ваше предыдущее расположение было хрупким (в котором у Вас были проблемы Вы фиксированный путем выяснения в том, какой порядок вызываемые методы платформы), можно найти, что эти проблемы возвратились при расположении на основе ограничений. Хотелось бы надеяться, в большинстве случаев самое простое решение будет состоять в том, чтобы принять расположение на основе ограничений для затронутых представлений. Если Вы - автор платформы, обеспечивающий пользовательские представления, и хотите избежать вовлекать расположение на основе ограничений в окно, можно выполнить любую необходимую работу в updateConstraints. Этот метод не вызывают, пока расположение на основе ограничений не занято. Кроме того, одна из целей updateConstraints это, это имеет четко определенную синхронизацию, подобную awakeFromNib, таким образом, можно найти, что проблемы проще разрешить в Автоматическом Расположении.

Существует граничный случай для знания. При реализации представления Вы могли бы реализовать всю свою ограничительную установку в пользовательском updateConstraints метод. Однако, потому что система на основе ограничений привлекается лениво, если ничто не устанавливает ограничения, Вашего updateConstraints метод никогда не будет вызываться. Для предотвращения этой проблемы можно переопределить requiresConstraintBasedLayout возвратиться YEStrue сигнализировать, что для Вашего представления нужно окно для использования расположения на основе ограничений.

Пример кода

Существует несколько демонстрационных приложений, демонстрирующих работу с API, группировался в “Демонстрациях Авторасположения Какао”.

FindPanelLayout является хорошим примером для запуска с. Выборка демонстрирует, как код в уровне контроллера использует API. Это размечает окно, которое довольно сложно с классическим расположением Какао, но это прямо с ограничениями. Пример иллюстрирует использование визуального языка формата, обнимающего содержание приоритета, RTL и поддержки локализации, автоматического размера минимума окна, визуализации для отладки и понятия неоднозначности как что-то, что может пойти не так, как надо.

SplitView демонстрирует API с точки зрения представления. Это реализует представление разделения с одной дополнительной функцией: Когда делитель перетаскивается, он продвигает другие делители из пути, при необходимости, и они хватают назад. SplitView иллюстрирует усовершенствованное использование приоритета, переопределяя updateConstraints, перетаскивание и ограничения, пересекающие иерархию представления.

DraggingAndWindowResize прежде всего демонстрирует, как Вы используете NSLayoutPriorityDragThatCanResizeWindow. Это показывает, что представление с его собственным перетаскиванием изменяет размеры поля в окне, таком как Safari имеет для многострочных доступных для редактирования текстовых представлений в веб-странице. Если окно должно стать больше для размещения перетаскивания, оно делает.

Layout.tracetemplate какао является шаблоном Instruments, упомянутым в Отладке. Шаблон не является демонстрационным приложением, но это может быть полезно для нахождения ошибок.