Ответ
Свойство bounds.origin определяет систему координат для отрисовки внутри view. Оно может быть ненулевым в двух основных случаях:
-
При скроллинге в
UIScrollView(и его подклассах):bounds.originравенcontentOffset. Он смещается, чтобы указать, какая часть внутреннего контента (contentSize) видна во frame.let scrollView = UIScrollView(frame: CGRect(x: 0, y: 0, width: 200, height: 200)) scrollView.contentSize = CGSize(width: 500, height: 500) scrollView.contentOffset = CGPoint(x: 150, y: 150) // Теперь видимая часть контента начинается с точки (150, 150) print(scrollView.bounds.origin) // (150.0, 150.0) -
После применения трансформации (
transform) кUIView: Система координат view (bounds) смещается, чтобы компенсировать трансформацию и упростить позиционирование subviews. Frame при этом меняется, а bounds.origin становится отрицательным.let view = UIView(frame: CGRect(x: 50, y: 50, width: 100, height: 100)) // Сдвигаем view визуально на 20 точек вправо и вниз view.transform = CGAffineTransform(translationX: 20, y: 20) // Система координат для рисования внутри view смещается в обратную сторону print(view.bounds.origin) // (-20.0, -20.0)
Ключевой момент: bounds.origin редко меняется вручную. Его нестандартное значение — это следствие скроллинга или трансформации, управляемых системой.
Ответ 18+ 🔞
О, слушай, вот эта штука с bounds.origin — это вообще отдельная песня, блядь. Казалось бы, ну origin, ну координаты, хуй с ним. Ан нет, сука, тут такие подлянки бывают, что волосы дыбом встают, ёпта.
Вот смотри, обычно у вьюхи bounds.origin стоит на (0, 0). Как будто так и надо. Но иногда, блядь, открываешь дебаггер, а там какая-то хуйня, типа (-20, -20). И ты такой: «Что за манда? Я же не трогал эту хуйню!»
А оказывается, это система сама, хитрая жопа, его меняет. И в основном по двум поводам, блядь.
Первый случай — это когда вьюха в скроллвью сидит. Тут всё логично, хоть и мозг набекрень ставит. bounds.origin у скроллвью становится равен его contentOffset. По сути, система координат внутри него сдвигается, чтобы показать, какая часть его огромного внутреннего контента сейчас видна в окошке. Это как через иллюминатор подводной лодки смотреть и двигать саму лодку, а не картинку за стеклом.
let scrollView = UIScrollView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
scrollView.contentSize = CGSize(width: 500, height: 500)
scrollView.contentOffset = CGPoint(x: 150, y: 150)
// Теперь видимая часть контента начинается с точки (150, 150)
print(scrollView.bounds.origin) // (150.0, 150.0)
Видишь? Мы скролльнули на (150, 150), и bounds.origin стал таким же. Всё сходится, мать его.
А второй случай — это вообще ёперный театр. Когда ты применяешь к вьюхе трансформацию, например, сдвигаешь её transform'ом. Система, блядь, чтобы subviews (дочерние вьюхи) внутри неё не ебнулись и оставались на своих местах, — сдвигает саму систему координат, bounds, в обратную сторону! А frame при этом меняется так, как будто вьюха реально сдвинулась. Получается пиздец какой-то разрыв шаблона.
let view = UIView(frame: CGRect(x: 50, y: 50, width: 100, height: 100))
// Сдвигаем view визуально на 20 точек вправо и вниз
view.transform = CGAffineTransform(translationX: 20, y: 20)
// Система координат для рисования внутри view смещается в обратную сторону
print(view.bounds.origin) // (-20.0, -20.0)
Смотри, что выходит: вьюха визуально сдвинулась. Но система координат для рисования внутри неё (bounds) уехала в минуса! Это чтобы, если ты внутри неё что-то рисуешь в точке (0, 0), это что-то оказалось в правильном месте после трансформации. Гениально и ебнуто одновременно, блядь.
Так что запомни главное, чувак: bounds.origin — это не та хуйня, которую ты обычно трогаешь руками. Это следствие, блядь. Следствие того, что где-то скролльнули или трансформ применили. Если видишь в нём не ноль — ищи, где накосячил со скроллом или анимацией. Или просто вспомни, что ты её двигал трансформом, и успокойся, ебать.