Что будет с bounds, если родителя повернуть на 45 градусов?
Комментарии (2)
Ответ сгенерирован нейросетью и может содержать ошибки
Влияние трансформации родителя на bounds дочернего представления
При повороте родительского UIView на 45 градусов с использованием свойства transform bounds дочернего представления не изменятся. Это один из фундаментальных принципов системы координат в iOS UIKit.
Ключевое отличие: frame vs bounds
Чтобы понять, почему bounds остаются неизменными, важно различать два основных свойства UIView:
frame— описывает положение и размер представления в системе координат его родителя (superview). Это прямоугольник, который "видит" родитель.bounds— описывает положение и размер представления в его собственной, внутренней системе координат. Начало координат (origin) обычно равно(0, 0), аsize— это внутренний размер контента. Изменениеbounds.originиспользуется для реализации прокрутки (UIScrollView).
Анализ сценария с поворотом
Когда вы применяете transform (например, поворот) к родительскому виду, вы трансформируете всю его систему координат, включая всех его сабвью. Однако bounds дочернего вида описывает его геометрию в его собственной, локальной системе координат, которая не затрагивается трансформацией родителя.
let parentView = UIView(frame: CGRect(x: 50, y: 50, width: 200, height: 200))
let childView = UIView(frame: CGRect(x: 20, y: 20, width: 100, height: 100))
parentView.addSubview(childView)
print("До трансформации - child.bounds: \(childView.bounds)")
// До трансформации - child.bounds: (0.0, 0.0, 100.0, 100.0)
// Применяем поворот родителю
parentView.transform = CGAffineTransform(rotationAngle: .pi / 4) // 45 градусов
print("После трансформации родителя - child.bounds: \(childView.bounds)")
// После трансформации родителя - child.bounds: (0.0, 0.0, 100.0, 100.0) -> НЕ ИЗМЕНИЛИСЬ!
print("После трансформации родителя - child.frame: \(childView.frame)")
// child.frame ИЗМЕНИЛСЯ, так как теперь он вычисляется в повёрнутой системе координат родителя.
Что происходит на самом деле?
- Система координат родителя поворачивается. Любая геометрия, выраженная в ней (включая
frameвсех сабвью), будет интерпретироваться через призму этой трансформации. - Локальная система координат дочернего вида (
bounds) остаётся неизменной. Его внутренняя геометрия (например, рисование вdrawRect:) и расстановка его собственных сабвью продолжают работать так, как будто ничего не произошло. - Свойство
frameдочернего вида становится вычисляемым. Посколькуframeопределяется как положениеboundsв системе координат родителя, UIKit вычисляет его, применяя трансформацию родителя к исходной геометрии. Часто это приводит к изменениюframe.originиframe.size(так как повёрнутый прямоугольник описывается новым, обрамляющим его прямоугольником, который обычно больше). - Важно: прямое изменение
frameпредставления, к которому или к родителю которого применена трансформация (не являющаяся единичной), может привести к неопределённому поведению, так как эти два свойства (frame,boundsиtransform) становятся не полностью независимыми.
Практический вывод и аналогия
- Bounds — это "внутренний паспорт" вида. Поворот родителя не меняет паспортных данных дочернего элемента, а лишь меняет то, как он ориентирован в пространстве (что и отражает
frame). - Аналогия: Представьте, что у вас есть лист бумаги (дочерний вид) с нарисованным на нем квадратом 10x10 см (его
bounds). Вы кладёте этот лист на стол (родительский вид). Если вы повернёте весь стол на 45 градусов, квадрат на листе ничуть не изменит своих размеров (bounds), но его положение относительно комнаты (frameв корневой системе координат) и проекция на пол изменятся.
Таким образом, при повороте родителя на 45 градусов bounds его дочерних представлений остаются прежними. Изменяется только их frame, так как он пересчитывается относительно новой (повёрнутой) системы координат родителя. Это поведение критически важно для корректной работы анимаций, рисования и вложенных иерархий представлений.