提问人:Logger 提问时间:11/7/2023 最后编辑:Logger 更新时间:11/7/2023 访问量:58
iOS:UIMenu 导致按钮操作仅触发一次。之后,每个后续的单击按钮操作都不会触发
iOS: UIMenu is causing the button action to trigger only once. After that every subsequent click button action is not triggering
问:
我有一个UIButon,并与之关联了一个UIMenu。单击显示 UIMenu 的按钮后。但是我可以观察到导致显示菜单的按钮操作仅调用一次,之后每个后续单击按钮操作都不会触发。可能是 UIMenu 以这样一种方式缓存按钮操作,即特定按钮操作仅调用一次。但是根据我的要求,每次单击按钮时都必须触发按钮操作。
下面我发布了示例代码,每次用户单击菜单选项时,我都尝试在控制台上打印随机数,并且每次打印相同的数字时我都可以看到。这是因为这段代码只在第一次调用 let randomNumber = Int(arc4random_uniform(10))
*导入 UIKit 类 ViewController: UIViewController {
var name = String()
var namesText = ["one", "Two", "Three", "Four", "Five", "six", "Seven","Eight", "Nine", "Ten"]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
@IBAction func buttonNewAction(_ sender: UIButton) {
self.showMenu(sender: sender)
}
func showMenu(sender: UIButton) {
let randomNumber = Int(arc4random_uniform(10))
let usersItem = UIAction(title: "Users", image: UIImage(systemName: "person.fill")) { (action) in
print("\(randomNumber) in User action")
}
let addUserItem = UIAction(title: "Add User", image: UIImage(systemName: "person.badge.plus")) { (action) in
print("\(randomNumber) in add user action")
}
let removeUserItem = UIAction(title: "Remove User", image: UIImage(systemName: "person.fill.xmark.rtl")) { (action) in
print("\(randomNumber) in Remove user")
}
let menu = UIMenu(title: "", children: [usersItem, addUserItem, removeUserItem])
sender.menu = menu
sender.showsMenuAsPrimaryAction = true
}
}*
答:
1赞
son
11/7/2023
#1
不能按子类 UIButton 重新分配按钮的菜单。然后重写 UIControl 委托,以在每次关闭菜单弹出框时删除 UIMenu 属性。contextMenuInteraction willEnd
更新:当您期待 UIMenu 时,始终在关闭时进行设置。当从 Button 的子类中删除 UIMenu 时,我做了一个技巧来处理回调,然后再次设置点击动作,因为只工作一次。.menuActionTriggered
class MenuButton: UIButton {
var onRemovedMenu: (() -> Void)?
override func contextMenuInteraction(_ interaction: UIContextMenuInteraction, willEndFor configuration: UIContextMenuConfiguration, animator: UIContextMenuInteractionAnimating?) {
super.contextMenuInteraction(interaction, willEndFor: configuration, animator: animator)
removeMenuWhenDismissed()
}
private func removeMenuWhenDismissed() {
self.menu = nil
onRemovedMenu?()
}
}
class MyViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let button = MenuButton()
button.showsMenuAsPrimaryAction = true
button.onRemovedMenu = { [weak self] in
//put delay to avoid warning log when dismissing and adding menu too close
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
self?.setupButton(button)
}
}
button.setTitle("TAP ME", for: .normal)
button.setTitleColor(.blue, for: .normal)
setupButton(button)
view.addSubview(button)
button.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
button.center = view.center
}
private func setupButton(_ button: MenuButton) {
button.menu = UIMenu(title: "")
//UIControler.Event to `menuActionTriggered`
button.addTarget(self, action: #selector(self.showMenu), for: .menuActionTriggered)
}
...
}
最终结果:
评论
0赞
Logger
11/7/2023
菜单按钮操作调用正常。但是我希望按钮操作func showMenu(sender: UIButton)始终在“TAP ME”按钮单击上调用。实际上,每次单击 TAPME 按钮时都必须触发此行( let randomNumber = Int(arc4random_uniform(10)) )。
0赞
son
11/7/2023
@Logger我编辑了答案,你可以看看。
0赞
Logger
11/7/2023
谢谢,它按预期工作。感谢您抽出宝贵时间研究它。干杯
1赞
son
11/7/2023
很高兴我能帮助xD
评论