另一个 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,这会导致再次显示菜单,并且它有我的子-中的菜单项符合预期。我知道这应该有效,因为“替换...”一直在执行。
我已经验证的事情:
- 我的 UITextView 的子class 是一个 UIView。
- UserInteractionIsEnabled 为真(因为我可以 select 文本)。
- 只有一个 window,但我在调用 canBecomeFirstResonder 的地方调用 self.window.makeKeyAndVisible()。
- 我已经实施了 canBecomeFirstResponder()(returning True)。 (它会在手势识别器调出第一个菜单之前调用,但不会在之后调用。)
- 我调用了 self.becomeFirstResponder()(尽管它已经调用了)。
- 我已经实现了 canPerformAction()。这在第一个菜单项和子菜单项中经常被调用。我 return 对于我想使用的项目是正确的。
还有什么?谢谢!!
我向 Apple 寻求帮助。解决方法是添加
sharedMC.hideMenu()
就在调用 showMenu()
之前。
我认为问题是我的代码不是最初显示菜单的代码,所以我不得不在我的代码显示它之前隐藏它。我注意到(从通知中)菜单根本没有正式“隐藏”(即使在按下我的翻译...按钮后它不再可见)。
我也试过只更改菜单项并调用 update()
,但这也没有用,可能是出于同样的原因。
在此先感谢您的帮助。我向您保证,我已经阅读了这里关于 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,这会导致再次显示菜单,并且它有我的子-中的菜单项符合预期。我知道这应该有效,因为“替换...”一直在执行。
我已经验证的事情:
- 我的 UITextView 的子class 是一个 UIView。
- UserInteractionIsEnabled 为真(因为我可以 select 文本)。
- 只有一个 window,但我在调用 canBecomeFirstResonder 的地方调用 self.window.makeKeyAndVisible()。
- 我已经实施了 canBecomeFirstResponder()(returning True)。 (它会在手势识别器调出第一个菜单之前调用,但不会在之后调用。)
- 我调用了 self.becomeFirstResponder()(尽管它已经调用了)。
- 我已经实现了 canPerformAction()。这在第一个菜单项和子菜单项中经常被调用。我 return 对于我想使用的项目是正确的。
还有什么?谢谢!!
我向 Apple 寻求帮助。解决方法是添加
sharedMC.hideMenu()
就在调用 showMenu()
之前。
我认为问题是我的代码不是最初显示菜单的代码,所以我不得不在我的代码显示它之前隐藏它。我注意到(从通知中)菜单根本没有正式“隐藏”(即使在按下我的翻译...按钮后它不再可见)。
我也试过只更改菜单项并调用 update()
,但这也没有用,可能是出于同样的原因。