Другой UIMenuController не отобразит проблему - PullRequest
1 голос
/ 08 июля 2020

и заранее спасибо за вашу помощь. Уверяю вас, что я прочитал здесь почти все о проблемах UIMenuController. Я действительно думаю, что все это покрыл. Ясно, что я что-то упустил.

Короче говоря, я пытаюсь воспроизвести поведение меню редактирования «Заменить ...» (но с моей собственной функцией, отличной от «Заменить»). (Если вы не знакомы, когда выбрано слово, опция Заменить ... в меню редактирования вызовет второе меню, которое показывает возможные альтернативные варианты написания слова.)

В UITextView ( sub -classed), я выделяю текст. Распознаватель жестов по умолчанию заставляет меню редактирования отображать ожидаемые элементы, включая добавленную мной опцию «Перевести ...». Когда я нажимаю «Перевести ...» в меню, меню закрывается и вызывает мой код выбора. Этот код меняет элементы меню на нужные мне подвыборы. Я звоню UIMenuController.shared.showMenu(from: self, rect: textBounds). Я вижу вызовы canPerformAction (), чтобы убедиться, что элементы «подменю», которые я добавил, распознаны, но меню никогда не появляется. Уведомление для willShowWindowNotification (которое происходит при открытии первого меню) не происходит для этого подменю.

Вот код:

@objc func translateSelectionMenu()
{
    let sharedMC = UIMenuController.shared
    // Create menu choices for the translate sub-menu.
    let charChoice = UIMenuItem(title: "To Chars", action: #selector(translateChars))
    let byteChoice = UIMenuItem(title: "Byte Decimal", action: #selector(translateByte))
    let halfChoice = UIMenuItem(title: "2-Byte Decimal", action: #selector(translateHalf))
    savedMenuItems = sharedMC.menuItems
    sharedMC.menuItems = [charChoice, byteChoice, halfChoice]

... for brevity, I've omitted the code here which determines the bounds of the user's
    text selection. The resulting numbers are shown below.

    let textBounds = CGRect(x: 114.1, y: 73, width: 48, height: 55) 
    // let windowBounds = convert(textBounds, to: nil)
    // sharedMC.update() not needed
    self.becomeFirstResponder()  // TextView is already the first responder. This does nothing.
    sharedMC.showMenu(from: self, rect: textBounds)
}

Обратите внимание, что TextView IS и должен оставаться первым респондентом. (При его изменении теряется выбор пользователя.) Итак, я реализовал все это в подклассе UITextView, который показывает текст пользователя. Я пробовал использовать границы, указанные в UITextView, и границы, связанные с окном, но ни один из них не работает.

Если я перемещаю одну из конечных точек выделенного текста или просто щелкаю выделение, это вызывает меню будет показан снова, и в нем есть мои пункты подменю, как и ожидалось. Я знаю, что это должно работать, потому что «Заменить ...» делает это все время.

Вещи, которые я проверил:

  1. Мой подкласс UITextView - это UIView.
  2. UserInteractionIsEnabled истинно (поскольку я могу выделить текст).
  3. Есть только одно окно, но я вызываю self.window.makeKeyAndVisible () в точке, где вызывается canBecomeFirstResonder.
  4. Я реализовал canBecomeFirstResponder () (возвращает True). (Он вызывается прямо перед тем, как распознаватель жестов откроет первое меню, но не после этого.)
  5. Я действительно вызываю self.becomeFirstResponder () (даже если он уже есть).
  6. У меня есть реализован canPerformAction (). Это часто вызывается как с элементами первого меню, так и с элементами подменю. Я возвращаю True для предметов, которые хочу использовать.

Что еще? Спасибо !!

1 Ответ

0 голосов
/ 17 июля 2020

Я попросил помощи у Apple. Исправление состоит в том, чтобы добавить

sharedMC.hideMenu()

прямо перед вызовом showMenu().

Я думаю, проблема в том, что мой код не соответствует первоначальному представлению меню, поэтому мне пришлось спрячь его до того, как мой код сможет это показать. Я замечаю (из уведомлений), что меню вообще не было официально «скрытым» (хотя оно перестало отображаться после нажатия моей кнопки «Перевести ...»).

Я также попытался просто изменить элементы меню и позвонить update(), но это тоже не сработало, вероятно, опять же по той же причине.

...