Ответ
Это два принципиально разных подхода к определению геометрии UIView.
Frame (Прямое задание рамки)
- Что это: Прямое назначение прямоугольника (
CGRect), определяющего относительно родительской системы координат:origin(x, y) — положение верхнего левого угла.size(width, height) — размеры.
- Характеристики:
- Статичный: Не адаптируется автоматически к изменениям размеров супервью (например, при повороте устройства).
- Производительный: Минимальные накладные расходы на вычисления.
- Пример:
let customView = UIView() customView.frame = CGRect(x: 20, y: 100, width: 200, height: 44) parentView.addSubview(customView)
Constraints (Auto Layout — Ограничения)
- Что это: Система декларативных правил (ограничений), которые описывают отношения между атрибутами видов (leading, top, width, centerX и т.д.). Система автоматически вычисляет
frameна основе этих правил. -
Характеристики:
- Адаптивный и динамичный: Позволяет создавать интерфейсы, которые автоматически перестраиваются под разные размеры экранов, ориентации и контент.
- Более сложный: Требует понимания системы приоритетов, активации/деактивации.
-
Пример (программно):
let customView = UIView() customView.translatesAutoresizingMaskIntoConstraints = false parentView.addSubview(customView) NSLayoutConstraint.activate([ customView.leadingAnchor.constraint(equalTo: parentView.leadingAnchor, constant: 20), customView.topAnchor.constraint(equalTo: parentView.topAnchor, constant: 100), customView.widthAnchor.constraint(equalToConstant: 200), customView.heightAnchor.constraint(equalToConstant: 44) ])
| Сравнение и рекомендации: | Аспект | Frame-based Layout | Auto Layout (Constraints) |
|---|---|---|---|
| Адаптивность | Низкая, требует ручного пересчета | Высокая, автоматическая подстройка | |
| Сложность | Низкая для простых случаев | Высокая, требует понимания системы | |
| Производительность | Высокая | Может быть ниже при сложных иерархиях | |
| Когда использовать | Кастомная анимация, draw(_:), высокопроизводительные scroll views, очень простые фиксированные layout'ы. |
Подавляющее большинство случаев — создание адаптивных интерфейсов. |
Важно: Нельзя смешивать подходы для одного view без отключения translatesAutoresizingMaskIntoConstraints = false. Auto Layout в конечном счете всегда вычисляет frame view.
Ответ 18+ 🔞
А, ну вот, опять про эти ваши фреймы и констрейнты, блядь! Слушай, да это же как два разных способа поставить стул в комнате, ёпта!
Фрейм (Тупое тыканье пальцем в координаты)
Ну, представь, ты пришёл в пустую комнату и говоришь: «Стоять тебе, сука, стулу, ровно в метре от левой стены и в двух метрах от потолка, и быть тебе шириной в полметра, блядь!» Вот это и есть фрейм. Ты просто берёшь и впендюриваешь прямоугольник в пространство родителя.
- Что это такое? Прямоугольник (
CGRect), который ты тупо назначаешь. Тамorigin— это где верхний левый угол будет торчать, аsize— ну, ширина-высота, чё уж тут. - Как оно?
- Дубовое. Повернул телефон — а стул так и остался висеть в воздухе на тех же координатах, потому что система координат родителя съехала. Ручками всё пересчитывай, мудак.
- Быстрое. Мозгов не надо, посчитал один раз — и всё, ебись оно конём.
- Пример, чтоб понятнее было:
let customView = UIView() customView.frame = CGRect(x: 20, y: 100, width: 200, height: 44) parentView.addSubview(customView)Всё, прилепил. Сиди, блядь, на месте.
Констрейнты (Auto Layout — Умные договорённости)
А это уже высший пилотаж, блядь. Ты не говоришь, где стоять. Ты говоришь: «Слушай, стул, ты у меня должен быть прижат левым боком к левой стене с отступом в 20 сантиметров. И сверху отступи от подоконника на 100. И шириной будь ровно 200, сука, ни сантиметром больше!» А система уже сама, хитрая жопа, вычисляет, где ему frame поставить, чтобы все эти условия выполнились.
- Что это? Система правил-договорённостей между вьюхами. Не координаты, а отношения: «мой левый край равен твоему левому краю», «моя высота равна твоей высоте, поделённой на два».
-
Как оно?
- Гибкое и адаптивное. Повернул телефон — система сама пересчитает, где чему быть, чтобы отношения сохранились. Вообще охуенно для разных экранов.
- Сложное, блядь. Можно так наконстрейнить, что система разведёт руками и скажет «я нихуя не понял, конфликт», и всё встанет.
-
Пример (программно, чтоб жизнь мёдом не казалась):
let customView = UIView() customView.translatesAutoresizingMaskIntoConstraints = false // ЭТО ВАЖНО, БЛЯДЬ! ГОВОРИМ "НЕ ПРЕВРАЩАЙ МОЙ ФРЕЙМ В КОНСТРЕЙНТЫ!" parentView.addSubview(customView) NSLayoutConstraint.activate([ customView.leadingAnchor.constraint(equalTo: parentView.leadingAnchor, constant: 20), customView.topAnchor.constraint(equalTo: parentView.topAnchor, constant: 100), customView.widthAnchor.constraint(equalToConstant: 200), customView.heightAnchor.constraint(equalToConstant: 44) ])Выглядит как заклинание, но по сути — те же самые условия про стул.
Так что же выбрать, ёпта?
Смотри, вот тебе табличка, а то у тебя глаза уже стеклянные:
| На что смотрим | Фреймы (тупой способ) | Констрейнты (умный способ) |
|---|---|---|
| Адаптивность | Нулевая. Сам всё двигай, ленивая жопа. | Выше крыши. Система сама всё пересчитает. |
| Сложность | Для простого — легко. Для сложного — ад. | Сначала нихуя не понятно, потом привыкаешь. |
| Скорость | Быстро, потому что просто числа. | Может тормозить, если наконстрейнишь целое полотно. |
| Когда юзать? | Кастомная анимация, ручная отрисовка в draw(_:), какие-нибудь хитрые скролл-вьюхи, ну или если вьюха одна и навсегда. |
В 95% случаев, блядь! Весь современный адаптивный интерфейс. |
И главное, запомни, как «Отче наш»: Нельзя для одной вьюхи одновременно тыкать её фреймом и вешать констрейнты, если не сказал translatesAutoresizingMaskIntoConstraints = false. А то система начнёт сама с собой спорить, и будет пиздец. В конечном счёте, Auto Layout — это такой хитрый калькулятор, который всё равно вычисляет тот самый итоговый frame. Просто делает это умно, а не в лоб.