Что хранит свойство frame у UIView?

Ответ

Свойство frame (CGRect) описывает положение и размер UIView в системе координат её родительской вью (superview).

Что хранится в frame:

  • origin.x и origin.y: Координаты левого верхнего угла вью относительно левого верхнего угла её superview.
  • size.width и size.height: Ширина и высота вью.

Критически важные нюансы:

  1. Зависимость от bounds и center: Значение frame является вычисляемым и зависит от bounds.size и center. Прямое изменение frame может неявно изменить center.
  2. Игнорирование трансформаций: frame становится неопределённым (CGRect.null), если к вью применён ненулевой transform (например, поворот). Для позиционирования трансформированной вью используйте center.
  3. Конфликт с Auto Layout: Прямая установка frame для вью, управляемой Auto Layout (имеющей constraints), приводит к конфликту. Система может перезаписать ваш frame на следующем цикле обновления лэйаута.

Пример:

// Создаём вью, позиционируя её в точке (20, 30) родительской вью
let view = UIView(frame: CGRect(x: 20, y: 30, width: 100, height: 50))
print(view.frame) // (x: 20.0, y: 30.0, width: 100.0, height: 50.0)

Ответ 18+ 🔞

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

Что там внутри, в этом frame?

  • origin.x и origin.y: Это как координаты левого верхнего угла твоей картины на стене. Отсчёт идёт от левого верхнего угла самой стены (то есть superview). Поставил x: 50 — отъехал на 50 точек вправо от края стены.
  • size.width и size.height: Ну, тут без сюрпризов — ширина и высота самой картины. Всё логично, казалось бы.

А теперь, сука, внимание, где собака зарыта и где можно обосраться:

  1. Он не самостоятельный, этот твой frame! Он — производная от двух других парней: bounds.size (размеры самой вью) и center (её середина). Попробуешь в лоб поменять frame — система хитро пересчитает center у себя в заднице, и ты потом удивляешься, почему всё съехало. Это как пытаться изменить площадь комнаты, двигая стены, — потолок-то тоже шевелится, блядь!

  2. Трансформации его ебут в хвост и гриву. Применил к вьюхе поворот на 45 градусов (transform) — и всё, frame превращается в тыкву, а точнее, в CGRect.null. Он больше не описывает реальный занимаемый прямоугольник. Хочешь двигать повёрнутую вьюху? Тыкай в center, это единственная точка, которая остаётся адекватной.

  3. Авто-Лейаут его просто ненавидит. Это главная причина, почему у всех всё плывёт. Если ты навесил констрейнты (эти ебучие constraint), а потом в коде лезешь с view.frame = CGRect(...) — ты объявляешь войну. На следующем же цикле обновления лэйаута система возьмёт и перезапишет твой красивый frame на то, что она считает правильным, исходя из констрейнтов. Получишь артефакты, дергания и необъяснимые баги. Выбирай: либо ручное расположение через frame/center, либо Auto Layout. Сидеть на двух стульях — получить промежностью по гвоздю.

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

// Рождаем вьюху сразу в нужном месте у родителя
let view = UIView(frame: CGRect(x: 20, y: 30, width: 100, height: 50))
print(view.frame) // (x: 20.0, y: 30.0, width: 100.0, height: 50.0)

Вот, поставили картину на стену. Но помни про три пункта выше, а то она у тебя или повиснет в воздухе после поворота, или Auto Layout её нахуй снесёт при первом же обновлении интерфейса.