В чем разница между .left и .leading (а также .right и .trailing) в iOS разработке?

«В чем разница между .left и .leading (а также .right и .trailing) в iOS разработке?» — вопрос из категории UIKit, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Разница между .left/.right и .leading/.trailing заключается в поддержке интернационализации и направлении письма (Left-to-Right или Right-to-Left).

  • .left и .rightабсолютные направления. Они всегда соответствуют левой и правой стороне экрана, независимо от языковых настроек пользователя.
  • .leading и .trailingлогические направления. Они адаптируются под текущую локализацию:
    • Для языков с письмом слева направо (LTR), таких как английский или русский: .leading = .left, .trailing = .right.
    • Для языков с письмом справа налево (RTL), таких как арабский или иврит: .leading = .right, .trailing = .left.

Когда использовать:

  • Используйте .leading и .trailing для выравнивания текста, отступов (padding) и расположения элементов интерфейса, которые должны зеркально отображаться для RTL языков. Это рекомендуемый подход.
  • Используйте .left и .right только для фиксированного, незеркалируемого позиционирования (например, для графических элементов, где направление имеет физический смысл).

Пример в SwiftUI:

VStack {
    // Адаптивное выравнивание (рекомендуется)
    Text("Hello, World!")
        .frame(maxWidth: .infinity, alignment: .leading) // Слева для LTR, справа для RTL
        .padding(.leading, 20) // Отступ будет адаптивным

    // Фиксированное выравнивание
    Text("Fixed Position")
        .frame(maxWidth: .infinity, alignment: .topLeft) // Всегда в левом верхнем углу
}

Пример в UIKit (Auto Layout):

// Адаптивные констрейнты (рекомендуется)
let constraints = [
    label.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 16),
    label.trailingAnchor.constraint(lessThanOrEqualTo: view.trailingAnchor, constant: -16)
]
// Фиксированные констрейнты
let fixedConstraints = [
    label.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 16)
]