【问题标题】:Another UIMenuController won't display problem另一个 UIMenuController 不会显示问题
【发布时间】:2020-10-29 09:08:07
【问题描述】:

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

简而言之,我正在尝试复制“替换...”编辑菜单行为(但我自己的功能与替换不同)。 (If you're not familiar, when a word is selected, the Replace... option in the edit menu will bring up a second menu which shows possible alternate spellings for the word.)

在 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 是并且必须保持第一响应者。 (更改它会丢失用户的选择。)所以我已经在显示用户文本的 UITextView 的子类中实现了所有这些。我尝试过使用 UITextView 引用的边界和窗口引用的边界,但都不起作用。

如果我移动所选文本的端点之一或只是单击选择,这会导致菜单再次显示,并且它按预期包含我的子菜单项。我知道这应该可行,因为“替换...”一直都是这样做的。

我已验证的内容:

  1. 我的 UITextView 子类是 UIView。
  2. UserInteractionIsEnabled 为真(因为我可以选择文本)。
  3. 只有一个窗口,但我在调用 canBecomeFirstResonder 时调用了 self.window.makeKeyAndVisible()。
  4. 我已经实现了 canBecomeFirstResponder()(返回 True)。 (它会在手势识别器调出第一个菜单之前调用,但不会在之后调用。)
  5. 我确实调用了 self.becomeFirstResponder()(即使它已经调用了)。
  6. 我已经实现了 canPerformAction()。这在第一个菜单和子菜单项中都被称为很多。对于我想要使用的项目,我返回 True。

还有什么?谢谢!!

【问题讨论】:

    标签: swift uitextview ios13 uimenucontroller


    【解决方案1】:

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

    sharedMC.hideMenu()
    

    就在致电showMenu()之前。

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

    我也尝试只更改 menuItems 并调用 update(),但这也没有用,可能出于同样的原因。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-12-12
      • 2018-10-03
      • 2019-04-11
      • 2020-11-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多