Middle
23
0
questionbank

Как система определяет, в какую вьюху попал касание?

Answer from sobes.tech neural network

Система использует два ключевых механизма: хит-тестирование (hit-testing) и иерархию вьюх.

  1. Хит-тестирование (Hit-testing): Фреймворк UIKit использует метод hitTest(_:with:) корневой вьюхи окна (UIWindow) для определения, какая вьюха находится под точкой касания. Этот метод рекурсивно обходит иерархию вьюх, начиная с корневой.

  2. Иерархия вьюх:

    • Метод hitTest(_:with:) сначала проверяет, находится ли точка касания внутри границ текущей вьюхи. Если нет, метод возвращает nil.
    • Если точка внутри границ, метод просматривает дочерние вьюхи в обратном порядке (от последней добавленной к первой). Для каждой дочерней вьюхи вызывается ее собственный метод hitTest(_:with:) с той же точкой касания (преобразованной в координаты дочерней вьюхи).
    • Первая дочерняя вьюха, чей метод hitTest(_:with:) возвращает не-nil результат (т.е. она или одна из ее дочерних вьюх содержит точку), считается "попавшей" и этот результат возвращается вверх по иерархии.
    • Если ни одна дочерняя вьюха не содержит точку касания, а текущая вьюха сама содержит точку и не имеет userInteractionEnabled = false, то система считает, что касание произошло в текущей вьюхе, и метод возвращает self.
    • Если userInteractionEnabled текущей вьюхи равно false или hidden равно true, или alpha меньше 0.01, метод возвращает nil, даже если точка внутри границ.

Процесс продолжается вниз по иерархии, пока не будет найдена самая нижняя в иерархии вьюха, содержащая точку касания. Эта вьюха становится hit-test view или hit-test result, и именно ей (или ее ближайшему подходящему предку) будет делегировано дальнейшее управление событием (методы touchesBegan, touchesMoved и т.д.).

Вот как можно переопределить hitTest или point(inside:with:) для кастомного поведения хит-тестирования:

swift

Система использует два ключевых механизма: хит-тестирование (hit-testing) и иерархию вьюх.

  1. Хит-тестирование (Hit-testing): Фреймворк UIKit использует метод hitTest(_:with:) корневой вьюхи окна (UIWindow) для определения, какая вьюха находится под точкой касания. Этот метод рекурсивно обходит иерархию вьюх, начиная с корневой.

  2. Иерархия вьюх:

    • Метод hitTest(_:with:) сначала проверяет, находится ли точка касания внутри границ текущей вьюхи. Если нет, метод возвращает nil.
    • Если точка внутри границ, метод просматривает дочерние вьюхи в обратном порядке (от последней добавленной к первой). Для каждой дочерней вьюхи вызывается ее собственный метод hitTest(_:with:) с той же точкой касания (преобразованной в координаты дочерней вьюхи).
    • Первая дочерняя вьюха, чей метод hitTest(_:with:) возвращает не-nil результат (т.е. она или одна из ее дочерних вьюх содержит точку), считается "попавшей" и этот результат возвращается вверх по иерархии.
    • Если ни одна дочерняя вьюха не содержит точку касания, а текущая вьюха сама содержит точку и не имеет userInteractionEnabled = false, то система считает, что касание произошло в текущей вьюхе, и метод возвращает self.
    • Если userInteractionEnabled текущей вьюхи равно false или hidden равно true, или alpha меньше 0.01, метод возвращает nil, даже если точка внутри границ.

Процесс продолжается вниз по иерархии, пока не будет найдена самая нижняя в иерархии вьюха, содержащая точку касания. Эта вьюха становится hit-test view или hit-test result, и именно ей (или ее ближайшему подходящему предку) будет делегировано дальнейшее управление событием (методы touchesBegan, touchesMoved и т.д.).

Вот как можно переопределить hitTest или point(inside:with:) для кастомного поведения хит-тестирования:

swift

Register or sign in to get access to full answers for all questions from the question bank.

uitouch-eventsevent-handlinghit-testinguser-inputviews