Другой UIMenuController не будет отображать проблему

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

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

В UITextView (подклассе) я выделяю текст. Распознаватель жестов по умолчанию заставляет меню редактирования отображать ожидаемые элементы, включая добавленную мной опцию «Перевести ...». Когда я нажимаю «Перевести ...» в меню, меню закрывается и вызывает мой селекторный код. Этот код меняет пункты меню на нужные мне подвыборы. Я звоню 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, и границы, связанные с окном, но ни один из них не работает.

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

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

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

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


person BarryD    schedule 08.07.2020    source источник


Ответы (1)


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

sharedMC.hideMenu()

прямо перед звонком на showMenu().

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

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

person BarryD    schedule 17.07.2020