Вопрос проверяет понимание различий между frame и bounds UIView при применении трансформаций слоя, что важно для корректного позиционирования и анимации элементов интерфейса.
В iOS и macOS UIView и его слой CALayer имеют свойства frame и bounds для определения геометрии. Frame описывает положение и размер вида в системе координат его супервида, в то время как bounds определяет внутреннюю систему координат самого вида (обычно начало в (0,0) и его размер).
Когда вы применяете аффинное преобразование (CGAffineTransform) через свойство layer.transform, геометрическая форма вида визуально изменяется (например, поворачивается или масштабируется). Однако внутренняя система координат (bounds) остаётся неизменной. Свойство frame становится производным от bounds, центра (center) и применённой трансформации. Из-за этого прямое чтение frame после применения трансформации может вернуть неожиданное значение (например, CGRect с отрицательными шириной или высотой после поворота на 45 градусов), так как система пытается вычислить минимальный ограничивающий прямоугольник, вмещающий трансформированный вид.
Рассмотрим код, который создаёт квадратный вид, применяет к нему поворот и выводит значения frame и bounds:
let view = UIView(frame: CGRect(x: 50, y: 50, width: 100, height: 100))
view.backgroundColor = .blue
print("До трансформации:")
print("Frame: \(view.frame)") // (50.0, 50.0, 100.0, 100.0)
print("Bounds: \(view.bounds)") // (0.0, 0.0, 100.0, 100.0)
// Применяем поворот на 45 градусов
view.layer.transform = CATransform3DMakeRotation(.pi / 4, 0, 0, 1)
print("\nПосле трансформации:")
print("Frame: \(view.frame)") // Может быть, например, (29.3, 29.3, 141.4, 141.4)
print("Bounds: \(view.bounds)") // (0.0, 0.0, 100.0, 100.0) - не изменилось!
print("Center: \(view.center)") // (100.0, 100.0) - остаётся корректнымКак видно, bounds не изменилось, а frame изменилось, отражая новый ограничивающий прямоугольник повёрнутого квадрата. Центр (center) остаётся надёжной точкой для позиционирования.
convert(_:to:).Вывод: При использовании layer.transform свойство frame становится ненадёжным для геометрических расчётов, так как оно вычисляется из bounds, центра и трансформации. Для корректной работы с трансформированными видами опирайтесь на неизменные bounds и center, а для позиционирования в иерархии видов используйте методы конвертации координат.