Ответ
Свойство frame (CGRect) описывает положение и размер UIView в системе координат её родительской вью (superview).
Что хранится в frame:
origin.xиorigin.y: Координаты левого верхнего угла вью относительно левого верхнего угла еёsuperview.size.widthиsize.height: Ширина и высота вью.
Критически важные нюансы:
- Зависимость от
boundsиcenter: Значениеframeявляется вычисляемым и зависит отbounds.sizeиcenter. Прямое изменениеframeможет неявно изменитьcenter. - Игнорирование трансформаций:
frameстановится неопределённым (CGRect.null), если к вью применён ненулевойtransform(например, поворот). Для позиционирования трансформированной вью используйтеcenter. - Конфликт с 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: Ну, тут без сюрпризов — ширина и высота самой картины. Всё логично, казалось бы.
А теперь, сука, внимание, где собака зарыта и где можно обосраться:
-
Он не самостоятельный, этот твой
frame! Он — производная от двух других парней:bounds.size(размеры самой вью) иcenter(её середина). Попробуешь в лоб поменятьframe— система хитро пересчитаетcenterу себя в заднице, и ты потом удивляешься, почему всё съехало. Это как пытаться изменить площадь комнаты, двигая стены, — потолок-то тоже шевелится, блядь! -
Трансформации его ебут в хвост и гриву. Применил к вьюхе поворот на 45 градусов (
transform) — и всё,frameпревращается в тыкву, а точнее, вCGRect.null. Он больше не описывает реальный занимаемый прямоугольник. Хочешь двигать повёрнутую вьюху? Тыкай вcenter, это единственная точка, которая остаётся адекватной. -
Авто-Лейаут его просто ненавидит. Это главная причина, почему у всех всё плывёт. Если ты навесил констрейнты (эти ебучие
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 её нахуй снесёт при первом же обновлении интерфейса.