另一个 UIMenuController 不会显示的问题

Another UIMenuController won't display problem

在此先感谢您的帮助。我向您保证,我已经阅读了这里关于 UIMenuController 问题的大部分内容。我真的认为我已经涵盖了所有内容。显然我错过了什么。

简而言之,我正在尝试复制“替换...”编辑菜单行为(但我自己的功能不同于替换)。 (如果您不熟悉,当 select 编辑一个单词时,编辑菜单中的替换...选项将弹出第二个菜单,其中显示该单词可能的替代拼写。)

在 UITextView(sub-classed)中,我 select 一些文本。默认手势识别器使编辑菜单出现预期的项目,包括我添加的“翻译...”选项。当我单击菜单中的“翻译...”时,菜单关闭并调用我的 selector 代码。该代码将菜单项更改为我想要的子选项。我打电话 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 是并且必须保持第一响应者。 (更改它会丢失用户 selection。)所以我在显示用户文本的 UITextView 的 subclass 中实现了所有这些。我试过使用 UITextView 引用的边界和 window 引用的边界,但都不起作用。

如果我移动 selected 文本的端点之一或只是单击 selection,这会导致再次显示菜单,并且它有我的子-中的菜单项符合预期。我知道这应该有效,因为“替换...”一直在执行。

我已经验证的事情:

  1. 我的 UITextView 的子class 是一个 UIView。
  2. UserInteractionIsEnabled 为真(因为我可以 select 文本)。
  3. 只有一个 window,但我在调用 canBecomeFirstResonder 的地方调用 self.window.makeKeyAndVisible()。
  4. 我已经实施了 canBecomeFirstResponder()(returning True)。 (它会在手势识别器调出第一个菜单之前调用,但不会在之后调用。)
  5. 我调用了 self.becomeFirstResponder()(尽管它已经调用了)。
  6. 我已经实现了 canPerformAction()。这在第一个菜单项和子菜单项中经常被调用。我 return 对于我想使用的项目是正确的。

还有什么?谢谢!!

我向 Apple 寻求帮助。解决方法是添加

sharedMC.hideMenu()

就在调用 showMenu() 之前。

我认为问题是我的代码不是最初显示菜单的代码,所以我不得不在我的代码显示它之前隐藏它。我注意到(从通知中)菜单根本没有正式“隐藏”(即使在按下我的翻译...按钮后它不再可见)。

我也试过只更改菜单项并调用 update(),但这也没有用,可能是出于同样的原因。