Какова иерархия наследования класса UIButton в UIKit?

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

Ответ

UIButton наследуется от UIControl, который, в свою очередь, наследуется от UIView. Полная цепочка наследования выглядит так:

NSObject → UIResponder → UIView → UIControl → UIButton

Что это означает на практике:

  1. От UIView: UIButton получает все свойства и методы для отображения на экране:

    • frame, bounds, backgroundColor
    • addSubview(_:), removeFromSuperview()
    • Система Auto Layout (translatesAutoresizingMaskIntoConstraints).
  2. От UIControl: UIButton наследует механизм Target-Action для обработки событий и управление состояниями:

    • addTarget(_:action:for:)
    • Свойство isEnabled
    • Состояния: .normal, .highlighted, .disabled, .selected.
  3. От UIResponder: Возможность участвовать в цепочке ответчиков (responder chain) для обработки событий касания, встряхивания и т.д.

  4. От NSObject: Базовая функциональность Objective-C runtime (например, KVO).

Пример проверки иерархии:

let button = UIButton()

// Проверка с помощью isKind(of:)
print(button.isKind(of: UIControl.self)) // true
print(button.isKind(of: UIView.self))    // true
print(button.isKind(of: UIResponder.self)) // true

// Вывод имени класса предка
print(type(of: button).superclass()) // Optional(UIControl)
print(UIControl.superclass())        // Optional(UIView)

Почему это важно? Понимание иерархии позволяет:

  • Предсказывать, какие методы и свойства доступны у UIButton.
  • Создавать кастомные кнопки, правильно переопределяя методы (например, touchesBegan из UIResponder или beginTracking из UIControl).
  • Эффективно использовать полиморфизм, работая с кнопкой как с UIView или UIControl.