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

Что такое UIGestureRecognizer?

1.0 Junior🔥 61 комментариев
#UIKit и верстка

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

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

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

UIGestureRecognizer: распознаватель жестов в iOS

UIGestureRecognizer — это абстрактный базовый класс в iOS фреймворке UIKit, который предоставляет механизм для распознавания и обработки различных типов жестов пользователя (тапов, свайпов, масштабирования и т.д.) на представлениях (UIView). Он инкапсулирует логику детектирования сложных паттернов касаний, преобразуя низкоуровневые события UITouch в высокоуровневые семантические жесты, что значительно упрощает разработку интерактивных интерфейсов.

Основные типы жестов (подклассы)

iOS предоставляет несколько конкретных подклассов для распознавания стандартных жестов:

  • UITapGestureRecognizer: Распознает один или несколько быстрых касаний.

    let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:)))
    tapGesture.numberOfTapsRequired = 1
    imageView.addGestureRecognizer(tapGesture)
    imageView.isUserInteractionEnabled = true // Важно!
    
  • UIPinchGestureRecognizer: Распознает "пинч" (сведение и разведение двух пальцев), обычно для масштабирования.

  • UIRotationGestureRecognizer: Распознает вращение двумя пальцами.

  • UISwipeGestureRecognizer: Распознает быстрые свайпы в одном из четырех направлений.

  • UIPanGestureRecognizer: Распознает непрерывное перетаскивание (пан).

  • UIScreenEdgePanGestureRecognizer: Подкласс UIPanGestureRecognizer, распознающий пан от края экрана (часто используется для навигации).

  • UILongPressGestureRecognizer: Распознает долгое нажатие.

Ключевые принципы работы и API

  1. Прикрепление к представлению: Каждый распознаватель привязывается к экземпляру UIView с помощью метода addGestureRecognizer(_:). Для обработки жестов у представления должно быть свойство isUserInteractionEnabled = true (по умолчанию true для интерактивных элементов, но false для UIImageView и UILabel).

  2. Target-Action паттерн: Инициализируется с целевым объектом (target) и методом-селектором (action), который будет вызван при распознавании жеста.

    let panGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePan(_:)))
    
  3. Состояния жеста (UIGestureRecognizer.State): В методе обработки можно анализировать состояние распознавателя, что особенно важно для непрерывных жестов (пан, пинч, вращение).

    @objc func handlePan(_ gesture: UIPanGestureRecognizer) {
        let translation = gesture.translation(in: gesture.view?.superview)
    
        switch gesture.state {
        case .began:
            // Начало жеста
        case .changed:
            // Жест продолжается, обновляем позицию view
            gesture.view?.center.x += translation.x
            gesture.setTranslation(.zero, in: gesture.view?.superview)
        case .ended, .cancelled:
            // Жест завершен или отменен
        default:
            break
        }
    }
    
  4. Делегирование (UIGestureRecognizerDelegate): Протокол позволяет тонко настраивать поведение жестов. Ключевые методы:

    *   `gestureRecognizerShouldBegin(_:)` — разрешить или запретить начало распознавания.
    *   `gestureRecognizer(_:shouldRecognizeSimultaneouslyWith:)` — разрешить одновременное распознавание несколькими жестами (например, пинч и вращение). Возврат `true` позволяет одновременно масштабировать и вращать объект.
    *   `gestureRecognizer(_:shouldRequireFailureOf:)` и `gestureRecognizer(_:shouldBeRequiredToFailBy:)` — устанавливать приоритеты и зависимости между жестами.

Важные аспекты для разработчика

  • Отмена и отказ: Система может отменить жест (например, при прерывании), или же распознаватель может перейти в состояние .failed, если движение не соответствует паттерну. Это важно для корректной обработки.
  • Отношения между жестами: На одном UIView может быть несколько распознавателей. Поведение по умолчанию — один жест блокирует другие. Для одновременной работы или установки приоритета (например, двойной тап блокирует одинарный) используются методы делегата или настройки вроде require(toFail:).
  • Наследование: Можно создавать собственные подклассы UIGestureRecognizer для распознавания нестандартных жестов, переопределяя методы обработки касаний (touchesBegan, touchesMoved, touchesEnded, touchesCancelled) и корректно обновляя state.
  • Взаимодействие с другими обработчиками: Жесты имеют более высокий приоритет, чем обычные обработчики касаний в UIResponder-цепочке. Но их можно интегрировать, используя ту же информацию об объектах UITouch.

Пример одновременного распознавания

class ViewController: UIViewController, UIGestureRecognizerDelegate {
    @IBOutlet weak var customView: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()

        let pinchGesture = UIPinchGestureRecognizer(target: self, action: #selector(handlePinch(_:)))
        let rotationGesture = UIRotationGestureRecognizer(target: self, action: #selector(handleRotation(_:)))

        // Назначаем делегата
        pinchGesture.delegate = self
        rotationGesture.delegate = self

        customView.addGestureRecognizer(pinchGesture)
        customView.addGestureRecognizer(rotationGesture)
    }

    // Разрешаем одновременное выполнение пинча и вращения
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return (gestureRecognizer is UIPinchGestureRecognizer && otherGestureRecognizer is UIRotationGestureRecognizer) ||
               (gestureRecognizer is UIRotationGestureRecognizer && otherGestureRecognizer is UIPinchGestureRecognizer)
    }

    @objc func handlePinch(_ gesture: UIPinchGestureRecognizer) {
        guard let view = gesture.view else { return }
        view.transform = view.transform.scaledBy(x: gesture.scale, y: gesture.scale)
        gesture.scale = 1.0 // Сброс масштаба
    }

    @objc func handleRotation(_ gesture: UIRotationGestureRecognizer) {
        guard let view = gesture.view else { return }
        view.transform = view.transform.rotated(by: gesture.rotation)
        gesture.rotation = 0 // Сброс вращения
    }
}

Итог: UIGestureRecognizer — это мощный и гибкий инструмент, который избавляет разработчика от необходимости вручную обрабатывать сложные последовательности касаний. Понимание его состояний, делегата и управления приоритетами жестов критически важно для создания отзывчивого, интуитивного и надежного пользовательского интерфейса в iOS-приложениях.

Что такое UIGestureRecognizer? | PrepBro