Отключить распознаватели жестов в * подвиде *, чтобы распознаватели жестов супервизора могли работать

#xcode #macos

#xcode #macos

Вопрос:

У меня есть NSView (холст), в который я добавляю набор подклассов TextView (маленькие прямоугольники). В классах TextView есть распознаватели жестов для перетаскивания (перемещения) и выбора.

Холст имеет два режима:

  • рисование
  • текст

В текстовом режиме я могу взаимодействовать с классами TextView — я могу нажимать на них, редактировать и т. Д.

Когда я переключаюсь в режим рисования, я хочу полностью отключить поля TextView, и все события / жесты будут захвачены холстом.

Таким образом, я могу выполнять события панорамирования / щелчка по всему холсту, а поля TextView должны быть видны, но в противном случае игнорироваться / отключаться.

Чтобы перейти в режим рисования, я отключаю поля TextView следующим образом (если логическое значение «рисование» равно true, тогда я отключаю всю обработку событий в полях TextView):

             foreach (var tv in textBoxes)
            {
                tv.Editable = !drawing;
                tv.Selectable = !drawing;

#if __IOS__
                tv.UserInteractionEnabled = !drawing;
#else
                tv.AcceptsTouchEvents = !drawing;
#endif
                foreach (var g in tv.GestureRecognizers)
                    g.Enabled = !drawing;
            }
 

Таким образом, все отлично работает между двумя режимами на iOS. На Mac все в основном работает, за одним исключением: в режиме рисования (когда жесты textview и textview отключены), если я запускаю жест поверх поля TextView, ничего не происходит. Ни обработчик жестов Canvas, НИ обработчик жестов TextView box не вызываются. Запуск жеста в любом другом месте работает нормально, и обработчик жестов Canvas получает его.

В общем, мой вопрос: как я могу полностью отключить жесты в подвиде, чтобы жест супервизора был распознан, даже если жест начинается поверх подвида.

Есть примеры передачи жеста в подпредставление, но здесь я хочу передать жест супервизору (который, как я думал, должен быть вершиной цепочки ответчиков).

Любой совет будет с благодарностью принят.

Ответ №1:

Кажется, что решение состоит в том, чтобы убедиться, что subview, который вы хотите получать жесты, должен быть вверху, иначе жесты, похоже, не доходят до него (это означает, что он должен быть последним элементом в массиве Subviews).

Другими словами, если другой подпредставление «A» находится над вашим подпредставлением «B» — и это подпредставление «A» полностью отключено без распознавателей жестов… это остановит распознавание любых жестов в «B».

Распознаватели жестов не должны использовать цепочку ответчиков… (это ясно указано в спецификациях UIGestureRecognizer, но не в спецификациях NSGestureRecognizer). Вот цитата из последнего:

События, полученные вашим приложением, автоматически пересылаются любым соответствующим распознавателям жестов, прежде чем они будут отправлены в соответствующее представление

Это не говорит о том, как события передаются по цепочке ответчиков для распознавателей жестов на Mac.

Итак, как упоминалось выше, выведите свой subview на передний план, чтобы убедиться, что его жесты будут распознаны. На Mac невозможно легко упорядочить подвиды NSView (в отличие от UIView, Который имеет BringToFront, SendToBack и т. Д.). Итак, лучший способ, который я нашел, — использовать SortSubviews с соответствующей функцией упорядочения.