← Назад к вопросам

В каком случае у Bounds изменится Origin?

1.6 Junior🔥 101 комментариев
#UIKit и верстка

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Когда изменяется Origin у UIView.bounds

Bounds UIView представляет прямоугольную область в собственной системе координат этого view. Он состоит из двух компонентов: origin (точка CGPoint, задающая начало системы координат внутри view) и size (CGSize, задающий ширину и высоту). В отличие от frame, который описывает положение view в системе координат его родителя (superview), bounds определяет внутреннюю геометрию. По умолчанию bounds.origin равен (0, 0).

Основной и самый распространённый случай изменения bounds.origin связан с реализацией скроллирующего поведения или сдвига внутреннего содержимого.

Основной случай: UIScrollView и его подклассы

Когда вы работаете с UIScrollView, UITableView, UICollectionView или любым другим скроллирующим view, изменение bounds.origin — это механизм, который система использует для реализации скроллинга.

let scrollView = UIScrollView(frame: CGRect(x: 0, y: 0, width: 300, height: 300))
scrollView.contentSize = CGSize(width: 1000, height: 1000)

// Изначально bounds.origin равен (0, 0)
print(scrollView.bounds.origin) // Output: (0.0, 0.0)

// При скроллинге вправо на 200 точек, bounds.origin изменяется
scrollView.contentOffset = CGPoint(x: 200, y: 0)

// Теперь bounds.origin отражает этот сдвиг
print(scrollView.bounds.origin) // Output: (200.0, 0.0)

Что здесь происходит?

  • contentOffset scrollView напрямую привязывается к bounds.origin.
  • Сдвиг origin изменяет "окно" (видимую область), через которое view показывает своё содержимое (contentSize).
  • Визуально это выглядит как перемещение содержимого, но технически — это перемещение "окна просмотра" (bounds) над статичным (или относительно статичным) внутренним содержимым.

Почему это работает именно так?

Этот подход согласуется с моделью координат UIKit:

  1. Система координат view всегда начинается в его bounds.origin.
  2. Все subviews (дочерние view) и внутреннее рисование (например, в drawRect) позиционируются относительно этой точки origin.
  3. Когда origin становится (200, 0), точка (0, 0) в системе координат содержимого теперь соответствует точке (-200, 0) в системе координат bounds. Таким образом, часть содержимого, которая была видна в начале, теперь "сдвинулась" за левую границу видимой области.

Другие практические случаи изменения bounds.origin

Хотя скроллирующие views — самый частый пример, существуют и другие, менее распространённые сценарии:

  1. Кастомная реализация скроллинга или панорамирования в собственном UIView. Если вы имитируете поведение скролла вручную, вы можете напрямую менять bounds.origin для перемещения "видимой порции" большого внутреннего контента.

  2. Сдвиг внутреннего содержимого для эффектов или анимаций. Например, для создания эффекта "параллакс" или плавного смещения заднего фона относительно foreground элементов.

  3. Корректировка при изменении layout или трансформациях. В очень специфических случаях компоновки (layout) изменение bounds.origin может быть использовано для корректного позиционирования subviews после сложных трансформаций или изменения frame родителя. Однако это требуется редко, так как система обычно автоматически управляет этим.

Ключевое отличие от frame.origin

Важно помнить фундаментальную разницу:

  • Изменение frame.origin перемещает view целиком в системе координат его superview.
  • Изменение bounds.origin перемещает систему координат внутри view, влияя на то, как расположено его внутреннее содержимое и subviews относительно его собственных границ.

Пример с subview при изменении bounds.origin

Рассмотрим влияние на позицию subview:

let containerView = UIView(frame: CGRect(x: 50, y: 50, width: 200, height: 200))
let subview = UIView(frame: CGRect(x: 20, y: 20, width: 50, height: 50))
containerView.addSubview(subview)

// Изначально subview находится в 20 точках от верхнего левого угла containerView
print(subview.frame.origin) // (20.0, 20.0)

// Мы изменяем bounds.origin containerView
containerView.bounds.origin = CGPoint(x: 30, y: 30)

// Теперь система координат containerView смещена.
// Subview, чья позиция в системе координат containerView всё ещё (20, 20),
// будет визуально отображаться относительно нового origin.
// Его положение относительно superview containerView изменилось:
// Новое видимое положение можно рассчитать, но frame.origin subview остался (20, 20).

Вывод: Изменение bounds.origin — это мощный, но специфичный инструмент, в основном зарезервированный системой для реализации скроллинга (UIScrollView и его потомки). В собственных реализациях его изменение требует глубокого понимания систем координат UIKit и используется для достижения эффектов перемещения "окна просмотра" над статичным внутренним содержимым.

В каком случае у Bounds изменится Origin? | PrepBro