Что такое констрейнт (NSLayoutConstraint) в Auto Layout?

Ответ

NSLayoutConstraint (констрейнт) — это объект, который описывает математическое соотношение между атрибутами (layout attributes) двух элементов интерфейса или элемента и его супервью в системе Auto Layout. Он определяет правила для позиционирования и задания размеров.

Основные компоненты констрейнта:

  • firstItem, firstAttribute: Первый элемент и его атрибут (например, .leading, .centerY, .width).
  • relation: Соотношение (==, >=, <=).
  • secondItem, secondAttribute: Второй элемент и его атрибут.
  • multiplier & constant: Множитель и константа для линейного уравнения: firstAttribute = secondAttribute * multiplier + constant.
  • priority: Приоритет (UILayoutPriority) от 1 до 1000 для разрешения конфликтов.
  • isActive: Флаг активности констрейнта.

Пример создания и активации констрейнтов:

let button = UIButton()
view.addSubview(button)
// 1. Обязательный шаг
button.translatesAutoresizingMaskIntoConstraints = false

// 2. Создание и активация
NSLayoutConstraint.activate([
    // Центрирование по X и Y
    button.centerXAnchor.constraint(equalTo: view.centerXAnchor),
    button.centerYAnchor.constraint(equalTo: view.centerYAnchor),
    // Фиксированная ширина и высота
    button.widthAnchor.constraint(equalToConstant: 200),
    button.heightAnchor.constraint(equalToConstant: 50)
])

Важные нюансы:

  • translatesAutoresizingMaskIntoConstraints = false необходимо устанавливать для всех элементов, чьи констрейнты задаются вручную.
  • Для создания однозначной и непротиворечивой (satisfiable) системы констрейнтов необходимо задать положение (X, Y) и размер (ширина, высота) для каждого элемента.
  • Динамическое включение/отключение констрейнтов через isActive эффективнее, чем их удаление и повторное создание.

Ответ 18+ 🔞

А, ну вот, опять эти ваши констрейнты, блядь! Ну слушай, сейчас я тебе так объясню, что ты, сука, сам от себя офигеешь.

Представь себе, что NSLayoutConstraint — это такой занудный, блядь, менеджер-перфекционист, который орет на все элементы интерфейса: «Стоять, сука, ровно! Я сказал, нахуй, ровно!». Он и есть тот самый объект, который математически, с калькулятором в руках, описывает, где чья жопа должна находиться относительно другой жопы. Либо относительно окна, в котором они все сидят, эти ваши кнопочки-лампочки.

Из чего же, из чего же, из чего же сделан этот наш констрейнт? А сделан он, блядь, вот из чего:

  • firstItem, firstAttribute: Это первый подопытный и его параметр, который мы будем привязывать. Ну, типа, «левый край этой кнопки» или «её пупок по вертикали».
  • relation: Это как они друг к другу относятся. Равны (==), больше или меньше. Банальная алгебра, епта, только для вьюх.
  • secondItem, secondAttribute: А это второй участник этих разборок. К чему, собственно, и привязываем первого.
  • multiplier & constant: А вот это уже, блядь, магия! Формула: firstAttribute = secondAttribute * multiplier + constant. Multiplier — это чтоб в полтора раза шире сделать, а constant — чтоб на 20 точек отодвинуть. Без этого — никуда.
  • priority: Приоритет, от 1 до 1000. Это на случай, когда правил нахуярили дофига и они друг другу противоречат. Система смотрит: «Ага, у этого правило важнее, на 999, щас его выполним, а этим, на 250, пошли нахуй, простите».
  • isActive: Просто флажок «работает/не работает». Выключил — и элемент снова свободен как ветер, пока его другие констрейнты не держат.

А вот как это, сука, выглядит в коде, на примере кнопки:

let button = UIButton()
view.addSubview(button)
// 1. САМОЕ ГЛАВНОЕ И ЕГО ВСЕ ЗАБЫВАЮТ, БЛЯДЬ!
button.translatesAutoresizingMaskIntoConstraints = false

// 2. Творим магию привязок
NSLayoutConstraint.activate([
    // Ставим кнопку ровно в центр, чтоб не дергалась
    button.centerXAnchor.constraint(equalTo: view.centerXAnchor),
    button.centerYAnchor.constraint(equalTo: view.centerYAnchor),
    // И чтоб не растягивалась как попало, фиксируем размер, блядь
    button.widthAnchor.constraint(equalToConstant: 200),
    button.heightAnchor.constraint(equalToConstant: 50)
])

И запомни раз и нахуй, как «Отче наш»:

  • translatesAutoresizingMaskIntoConstraints = false — это святое. Не поставишь — получишь в консоль истерику системы и вьюху, уехавшую в неизвестном направлении. Это как отключить автопилот, прежде чем самому рулить.
  • Чтобы система не сошла с ума, нужно четко, блядь, определить для каждой вьюхи где её левый-верхний угол (X, Y) и какая у неё ширина с высотой. Иначе Auto Layout тебе такого наворотит — волосы дыбом встанут.
  • Хочешь анимировать или временно убрать привязку? Не надо, блядь, удалять констрейнт и создавать новый! Проще переключить его свойство isActive. И памяти меньше жрет, и тебе спокойнее.