В UIKit, когда bounds view может быть больше, чем его frame?

Ответ

bounds описывает внутреннюю систему координат view (относительно себя), а frame — ее положение и размер в системе координат супервью. bounds может стать больше frame в следующих случаях:

  1. Применение аффинных трансформаций (transform). Это самый частый случай. Трансформация (масштабирование, поворот) меняет видимое содержимое, но не меняет frame (который становится "недействительным"). Система увеличивает bounds, чтобы вместить трансформированное содержимое.

    // frame останется (0, 0, 100, 100), но bounds станет больше
    view.transform = CGAffineTransform(scaleX: 2.0, y: 2.0)
  2. Изменение anchorPoint слоя (layer.anchorPoint). Смещает точку привязки для трансформаций, что может привести к расхождению между bounds и frame.

  3. Когда subview выходит за границы superview с clipsToBounds = false. Это не меняет bounds самого view, но является смежным случаем, иллюстрирующим разницу между внутренними (bounds) и внешними (frame) координатами.

Ключевой вывод: Если к view применена неединичная трансформация, всегда работайте с bounds и center для манипуляций размещением и размером. Свойство frame в этом случае вычисляется системой и может давать неожиданные значения.

Ответ 18+ 🔞

Слушай, вот объясняю, как в баре после третьего стакана. Представь, что у тебя есть картина в раме. Это твое UIView.

  • frame — это где висит эта рама на стене (в координатах комнаты-супервью). Её размер и положение.
  • bounds — это внутренний холст самой картины. Его система координат начинается с (0,0) в его собственном левом верхнем углу.

Так вот, когда bounds становится БОЛЬШЕ, чем frame — это пиздец как контринтуитивно. Как так-то? Холст больше рамы? А вот так, блядь.

Самый частый пиздец — это трансформации (transform).

Допустим, у тебя вьюха размером 100x100. frame = (0,0,100,100), bounds = (0,0,100,100). Всё логично. А потом ты её, сука, масштабируешь:

myView.transform = CGAffineTransform(scaleX: 2.0, y: 2.0)

Что происходит? Визуально твоя вьюха стала в два раза больше. Но система, ёпта, хитрая жопа. Она НЕ МЕНЯЕТ frame! Он так и останется (0,0,100,100), потому что это "зарезервированное место" в родительском вью. А вот bounds — он описывает, какое пространство нужно, чтобы вместить всё своё ебаное содержимое после трансформации. И он вырастет! Может стать, например, (0,0,200,200). Чтобы влезла эта раздувшаяся хрень.

Получается пиздатая картина: рама на стене (frame) скромная, 100x100, а холст внутри (bounds) — овердохуищный, 200x200. Система просто отрисовывает центральную часть этого большого холста в маленькой раме.

Ещё один загон — anchorPoint. Это точка, вокруг которой всё вертится (буквально). Сдвинешь её — и все расчёты frame поедут куда левая пятка захочет, а bounds опять может оказаться больше.

Короче, главный вывод, который надо выжечь в мозгу калёным железом:

Если ты накосячил с transform (повернул, масштабировал), забудь про frame как про страшный сон. Он тебе врёт, как последний сукин сын. Для любых манипуляций с размером и положением работай только с bounds и center. frame в этом случае — это вычисляемое системой поле, которое можно только читать, а пытаться его менять — это прямой путь в ад непредсказуемого поведения. В рот меня чих-пых, сколько раз на этом обжигались!