Авто макет доступен уже несколько лет, но с iPhone 6 и 6 Plus он стал необходимостью для проектов. Хотя это не всегда было особенно легко в использовании, Xcode постоянно видел улучшения в Интерфейсном Разработчике, чтобы упростить интеграцию Auto Layout. В этом руководстве вы узнаете, как использовать язык визуальных форматов с помощью Swift для создания ограничений Auto Layout в коде.
1. Введение
В этом уроке предполагается, что у вас есть некоторые знания об автоматической компоновке Если вы новый Auto Layout, тогда я советую вам сначала прочитать вступление Джойса Эчессы .
Язык визуального формата — это декларативный язык, который используется для определения ограничений Auto Layout для представлений. Его синтаксис выразителен и прост для понимания, когда вы просматриваете код. Предполагаемые ограничения должны быть немедленно сняты с чтения оператора языка визуального формата, и они очень похожи на предложение.
 Ограничения Auto Layout с различными приоритетами, вертикальными макетами, интервалами и размерами могут быть созданы с использованием синтаксиса Visual Format Language.  Он определяется внутри строковой переменной и затем передается в методы уровня класса constraintsWithVisualFormat:options:metrics:views: and 
  constraintWithItem:attribute:relatedBy:toItem:attribute:multiplier:constant: класса NSLayoutConstraint . 
Язык визуального формата может быть особенно полезен, когда в Интерфейсном Разработчике нет возможности добавить ограничения Auto Layout, например, когда часть пользовательского интерфейса вашего приложения должна быть создана программно.
2. Создание нового проекта
Давайте создадим новый проект в XCode, чтобы увидеть, как используется язык визуального формата и как ваши проекты могут извлечь из этого пользу.
Шаг 1: Шаблон проекта
Откройте Xcode и выберите New> Project … из меню File . Выберите Single View Application из списка шаблонов приложений iOS и нажмите Next .

Шаг 2: Конфигурация проекта
Затем назовите ваш проект и введите название и идентификатор вашей организации. Выберите « Универсальный» в списке « Устройства» , нажмите « Далее» и выберите место для сохранения проекта. Выберите Swift в качестве языка программирования.

3. Создание ограничения для одного представления
Шаг 1: Определите переменные
  Для начала создайте три переменные типа UIView .  Откройте ViewController.swift и добавьте следующий код над методом viewDidLoad : 
| 1 2 3 | var vwBlue:UIView! var vwRed:UIView! var vwGreen:UIView! | 
Шаг 2. Инициализация представлений
  Создайте функцию с именем initViews в нижней части контроллера представления void качестве его возвращаемого типа.  Эта функция инициализирует представления и добавляет их в иерархию представлений.  Обязательно вызовите эту функцию в viewDidLoad после вызова метода viewDidLoad суперкласса. 
| 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 | func initViews() -> Void {     //Initialize     vwRed = UIView()     vwBlue = UIView()     vwGreen = UIView()         //Prep auto layout     vwRed.setTranslatesAutoresizingMaskIntoConstraints(false)     vwBlue.setTranslatesAutoresizingMaskIntoConstraints(false)     vwGreen.setTranslatesAutoresizingMaskIntoConstraints(false)         //Coloring     vwRed.backgroundColor = UIColor.redColor()     vwBlue.backgroundColor = UIColor.blueColor()     vwGreen.backgroundColor = UIColor.greenColor()         //Add them to the view     self.view.addSubview(vwRed)     self.view.addSubview(vwBlue)     self.view.addSubview(vwGreen) } | 
  При использовании Auto Layout для представлений, созданных в коде, необходимо учитывать несколько предостережений.  Первый связан со значением свойства translatesAutoresizingMaskIntoConstraints .  Это свойство имеет значение true по умолчанию, что означает, что ограничения Auto Layout будут созданы на основе маски авторазмера представления .  Мы хотим, чтобы представление соблюдало ограничения Auto Layout, которые мы добавим, поэтому для этого свойства должно быть установлено значение false . 
Второе, что нужно иметь в виду, это жизненный цикл представления. Прежде чем ограничения Auto Layout могут быть добавлены в представление, его необходимо добавить в суперпредставление. В противном случае возникает исключение времени выполнения. Напомним, что Auto Layout определяет, где расположены представления на основе отношений. Если представление не имеет суперпредставления, операционная система не имеет контрольной точки, с которой можно связать ограничения Auto Layout.
Шаг 3. Создание ограничений для одного представления
  Давайте начнем с простого примера языка визуального формата.  Для красного представления vwRed мы добавим ограничения Auto Layout, которые сделают его такого же размера, как и его суперпредставление.  Это полезно в сценарии, где вы добавляете фоновое изображение. 
Прежде чем использовать язык визуального формата, все слова, которые нам нужны, должны быть указаны в словаре. Вот как представления будут идентифицироваться языком визуального формата.
  Создайте функцию с именем createConstraints с возвращаемым void типом в нижней части класса контроллера представления.  Не беспокойтесь о синтаксисе.  Мы еще createConstraints к createConstraints функции createConstraints . 
| 01 02 03 04 05 06 07 08 09 10 11 12 13 | func createConstraints() -> Void {     //Views to add constraints to     let views = Dictionary(dictionaryLiteral: («red»,vwRed),(«blue»,vwBlue),(«green»,vwGreen))         //Horizontal constraints     let horizontalConstraints = NSLayoutConstraint.constraintsWithVisualFormat(«H:|[red]|», options: nil, metrics: nil, views: views)     self.view.addConstraints(horizontalConstraints)         //Vertical constraints     let verticalConstraints = NSLayoutConstraint.constraintsWithVisualFormat(«V:|[red]|», options: nil, metrics: nil, views: views)     self.view.addConstraints(verticalConstraints) } | 
Шаг 4: Сборка и запуск
  Вызовите эту функцию в конце функции initViews мы создали ранее.  Создайте и запустите проект, нажав Ctrl + R или нажав кнопку воспроизведения в левом верхнем углу.  Симулятор iOS запустится, показывая красный вид, занимающий весь экран, как и предполагалось. 

4. Анализ синтаксиса языка визуальных форматов
При использовании языка визуальных форматов ограничения автоматического макета определяются по горизонтали или по вертикали. Вы также можете определить высоту или ширину вида при объявлении вертикального и горизонтального ограничения соответственно. Давайте подробнее рассмотрим первую строку, которую мы использовали для создания горизонтального ограничения.
 "H:|[red]|"  
  Сначала мы определяем, что это будет горизонтальное ограничение, начиная строку с буквы H  По умолчанию используется горизонталь, но рекомендуется включить ее, чтобы сделать ее более очевидной.  За направлением ограничения следует двоеточие. 
  |  или символ трубы символизирует суперпредставление представления.  Чтобы добавить пробел между двумя элементами, используется символ - или тире, и между ними можно поместить целочисленные значения, чтобы создать фиксированный или переменный интервал.  На ссылки ссылаются ключи, предоставленные в словаре, переданные в constraintsWithVisualFormat .  Каждый вид заключен в квадратные скобки. 
Обратите внимание, как вся строка визуально соответствует изображению из симулятора. Это написано как предложение, которое будет читать что-то вроде: «По горизонтали красный вид должен расширять всю ширину своего суперпредставления без заполнения».
5. Создание ограничений для нескольких представлений
  Теперь, когда у вас есть createConstraints представление о синтаксисе, мы собираемся отредактировать функцию createConstraints чтобы добавить ограничения Auto Layout для двух представлений. 
  Шаг 1: Редактировать горизонтальное ограничение 
  В функции createConstraints отредактируйте переменную horizontalConstraints как показано ниже. 
| 1 2 3 | //Horizontal constraints let horizontalConstraints = NSLayoutConstraint.constraintsWithVisualFormat(«H:|-10-[red(>=100,<=200)]-0-[blue(==red)]-10-|», options: nil, metrics: nil, views: views) self.view.addConstraints(horizontalConstraints) | 
Этот фрагмент кода действительно показывает гибкость языка визуальных форматов. Вышеприведенный оператор создает для нас ряд ограничений Auto Layout. Рядом с именем представления горизонтальные размеры определены в скобках. Для красного вида размер должен быть больше или равен 100 точкам, но меньше или равен 200 точкам.
  Синий вид указывает, что он должен иметь такой же горизонтальный размер, как и красный вид, используя ==red в скобках.  Это удобный способ указать, что несколько представлений должны иметь одинаковый размер.  Создайте и запустите приложение в iOS Simulator.  Результат должен выглядеть как на скриншоте ниже. 

  Шаг 2: Добавление приоритетов 
Когда приложение запущено в симуляторе iOS, нажмите Ctrl + стрелка влево, чтобы изменить ориентацию симулятора iOS на альбомную. Пока приложение все еще работает нормально, в консоли Xcode появилось предупреждение. Предупреждение говорит нам, что некоторые ограничения Auto Layout не могут быть выполнены. Хотя это не приведет к сбою приложения, оно может привести к неожиданным результатам в пользовательском интерфейсе приложения.

  Это происходит потому, что два созданных нами вида не могут иметь ширину 200 точек и не иметь промежутков между ними, когда устройство или симулятор iOS находятся в горизонтальной плоскости.  Auto Layout решает эти типы сценариев, используя приоритеты.  Язык визуального формата позволяет определять приоритеты с помощью символа @ .  Отредактируйте переменную horizontalConstraints чтобы она читалась следующим образом: 
| 1 2 | //Horizontal constraints let horizontalConstraints = NSLayoutConstraint.constraintsWithVisualFormat(«H:|-10-[red(>=100,<=200@20)]-0-[blue(==red)]-10-|», options: nil, metrics: nil, views: views) | 
  Поскольку красные и синие представления теперь имеют низкий приоритет ограничения ширины, обозначенный @20 , система автоматической компоновки нарушит эти ограничения и предоставит им правильное значение во время выполнения.  Запустите приложение еще раз и измените ориентацию на альбомную.  Представления теперь заполняют дополнительное пространство, и XCode не производит никаких предупреждений. 

Шаг 3. Добавление ограничений в вид снизу
  Далее мы создадим ограничения для зеленого вида.  Обновите реализацию функции createConstraints как показано ниже. 
| 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 | func createConstraints() -> Void {     //Views to add constraints to     let views = Dictionary(dictionaryLiteral: («red»,vwRed),(«blue»,vwBlue),(«green»,vwGreen))         //Horizontal constraints     let horizontalConstraintsRedBlue = NSLayoutConstraint.constraintsWithVisualFormat(«H:|-10-[red(>=100,<=200@20)]-0-[blue(==red)]-10-|», options: nil, metrics: nil, views: views)     self.view.addConstraints(horizontalConstraintsRedBlue)     let horizontalConstraintsGreen = NSLayoutConstraint.constraintsWithVisualFormat(«H:|[green]|», options: nil, metrics: nil, views: views)     self.view.addConstraints(horizontalConstraintsGreen)         //Vertical constraints     let verticalConstraintsRed = NSLayoutConstraint.constraintsWithVisualFormat(«V:|[red]-10-[green(40)]|», options: nil, metrics: nil, views: views)     self.view.addConstraints(verticalConstraintsRed)     let verticalConstraintsBlue = NSLayoutConstraint.constraintsWithVisualFormat(«V:|[blue]-10-[green(40)]|», options: nil, metrics: nil, views: views)     self.view.addConstraints(verticalConstraintsBlue) } | 
  Поскольку ограничение horizontalConstraintsGreen не определяет конкретную ширину или интервал для своего суперпредставления, оно будет охватывать всю длину.  Вертикальное ограничение гарантирует, что оно будет 40 точек высотой с 10 точками расстояния между красным и синим видами. 
Если вы запустите приложение еще раз, зеленый вид охватывает всю ширину экрана, а красный и синий вид останутся над ним, как и прежде. Когда симулятор iOS поворачивается в горизонтальное положение, представления сохраняют свои позиции и соответственно изменяют размер.

Шаг 4: Добавление метрик
Чтобы сделать все более читабельным, мы будем использовать словарь метрик в объявлениях ограничений. Создайте словарь, как показано ниже, сразу после объявления словаря представлений.
| 1 | let metrics = Dictionary(dictionaryLiteral: («spacing», 10),(«lowWidth»,100),(«highWidth»,200),(«priority»,20),(«redBlueSpacing»,0),(«greenHeight»,40)) | 
  Теперь вместо использования жестко закодированных значений мы можем использовать значения словаря metrics , что делает объявления ограничений более читабельными.  Отредактируйте функцию createConstraints последний раз, используя новый словарь metrics . 
| 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 | func createConstraints() -> Void {     //Views to add constraints to     let views = Dictionary(dictionaryLiteral: («red»,vwRed),(«blue»,vwBlue),(«green»,vwGreen))     //Metrics for Visual Format string     let metrics = Dictionary(dictionaryLiteral: («spacing», 10),(«lowWidth»,100),(«highWidth»,200),(«priority»,20),(«redBlueSpacing»,0),(«greenHeight»,40))         //Horizontal constraints     let horizontalConstraintsRedBlue = NSLayoutConstraint.constraintsWithVisualFormat(«H:|-spacing-[red(>=lowWidth,<=highWidth@priority)]-redBlueSpacing-[blue(==red)]-spacing-|», options: nil, metrics: metrics, views: views)     self.view.addConstraints(horizontalConstraintsRedBlue)     let horizontalConstraintsGreen = NSLayoutConstraint.constraintsWithVisualFormat(«H:|[green]|», options: nil, metrics: nil, views: views)     self.view.addConstraints(horizontalConstraintsGreen)         //Vertical constraints     let verticalConstraintsRed = NSLayoutConstraint.constraintsWithVisualFormat(«V:|[red]-spacing-[green(greenHeight)]|», options: nil, metrics: metrics, views: views)     self.view.addConstraints(verticalConstraintsRed)     let verticalConstraintsBlue = NSLayoutConstraint.constraintsWithVisualFormat(«V:|[blue]-spacing-[green(greenHeight)]|», options: nil, metrics: metrics, views: views)     self.view.addConstraints(verticalConstraintsBlue) } | 
6. Ограничения языка визуального формата
Вы можете быть удивлены, почему высота зеленого вида была определена дважды. Это потому, что язык визуального формата работает в строках и столбцах. При использовании языка визуальных форматов подумайте о добавлении ограничений слева направо на одну «строку» представления для горизонтальных ограничений. Для вертикальных ограничений вы должны думать о столбцах.
Большинство ограничений Auto Layout, которые вы будете использовать, могут быть выражены с помощью языка визуального формата. Однако есть некоторые, которые не могут. Например, ограничение фиксированного соотношения сторон не может быть создано с использованием языка визуального формата. Это не может быть выполнено с помощью синтаксиса Visual Format Language, потому что следующая строка не может быть проанализирована:
 H:|imageView.width = 2 * imageView.height|  
  Вы все еще можете использовать Auto Layout в своем коде для достижения этих типов ограничений, используя традиционный метод constraintWithItem . 
  Вывод 
Язык визуального формата может быть очень полезен, когда вам нужно создать ограничения Auto Layout в коде. Вместо того, чтобы создавать ограничения одно за другим, язык визуального формата позволяет создавать ряд ограничений с помощью одной строки кода.
До того, как Auto Layout был доступен для разработчиков, отслеживание того, как изменить размеры представлений для различных категорий устройств, было большой работой. Благодаря Auto Layout и Visual Format Language это стало более интуитивно понятным, что упрощает поддержку пользовательских интерфейсов на всех устройствах.