В UIKit, когда у `bounds` стандартного компонента `origin` может быть отличен от нуля?

«В UIKit, когда у `bounds` стандартного компонента `origin` может быть отличен от нуля?» — вопрос из категории UIKit, который задают на 22% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Свойство bounds.origin определяет систему координат для отрисовки внутри view. Оно может быть ненулевым в двух основных случаях:

  1. При скроллинге в 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)
  2. После применения трансформации (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 редко меняется вручную. Его нестандартное значение — это следствие скроллинга или трансформации, управляемых системой.