swift 为什么必须单击UIButton两次才能打开菜单?

uoifb46i  于 2023-01-04  发布在  Swift
关注(0)|答案(3)|浏览(167)

我有一个UIButton和一个UIMenu。当我运行应用程序时,我必须点击两次按钮才能看到菜单。只有第一次。如果我再次点击按钮,菜单就会立即打开。在模拟器和实际设备上都试过了。运行Xcode 14.2和Swift 5。
我试着将按钮的角色标记为primary。我试着将按钮的状态标记为已选中。不确定还能尝试什么。此外,尝试重新启动Xcode,以防Xcode中出现一些bug。

@IBAction func oxygenButtonPressed(_ sender: UIButton) {
        let twolpm = UIAction(title: "2 LPM") { (action) in
            self.dateFormatter.dateFormat = "HH:mm:ss"
            self.codeLog.append(CodeLog(event: (sender.titleLabel?.text)!, time: (self.dateFormatter.string(from: self.date)), note: "2LPM"))}
        let fourlpm = UIAction(title: "4 LPM") { (action) in
            self.dateFormatter.dateFormat = "HH:mm:ss"
            self.codeLog.append(CodeLog(event: (sender.titleLabel?.text)!, time: (self.dateFormatter.string(from: self.date)), note: "4LPM"))}
        let sixlpm = UIAction(title: "6 LPM") { (action) in
            self.dateFormatter.dateFormat = "HH:mm:ss"
            self.codeLog.append(CodeLog(event: (sender.titleLabel?.text)!, time: (self.dateFormatter.string(from: self.date)), note: "6LPM"))}
        let eightlpm = UIAction(title: "8 LPM") { (action) in
            self.dateFormatter.dateFormat = "HH:mm:ss"
            self.codeLog.append(CodeLog(event: (sender.titleLabel?.text)!, time: (self.dateFormatter.string(from: self.date)), note: "8LPM"))}
        let tenlpm = UIAction(title: "10 LPM") { (action) in
            self.dateFormatter.dateFormat = "HH:mm:ss"
            self.codeLog.append(CodeLog(event: (sender.titleLabel?.text)!, time: (self.dateFormatter.string(from: self.date)), note: "10LPM"))}
        let fifteenlpm = UIAction(title: "15 LPM") { (action) in
            self.dateFormatter.dateFormat = "HH:mm:ss"
            self.codeLog.append(CodeLog(event: (sender.titleLabel?.text)!, time: (self.dateFormatter.string(from: self.date)), note: "15LPM"))}
        let oxygenmenu = UIMenu(title: "Oxygen Menu", options: .displayInline, children:
                                    [twolpm, fourlpm, sixlpm, eightlpm, tenlpm, fifteenlpm])
        sender.showsMenuAsPrimaryAction = true
        sender.menu = oxygenmenu
    }
r55awzrz

r55awzrz1#

当我运行应用程序时,我必须点击两次按钮才能看到菜单。
是的。因为这正是你的代码说应该发生的。
想一想,你的动作方法在按钮被点击时运行,你的动作方法添加菜单。
因此,当你第一次点击按钮时,没有菜单,但是操作方法运行并添加了菜单--仅此而已。

  • 第二次 * 点击按钮时,按钮已经有菜单,因为第一次点击时添加了它;现在菜单打开。
rqmkfv5c

rqmkfv5c2#

你需要在点击按钮之前设置按钮的menushowsMenuAsPrimaryAction属性,所以你可能想在视图控制器的viewDidLoad方法中完成,然后(在故事板中)你应该删除按钮与oxygenButtonPressed方法的连接,并完全删除oxygenButtonPressed方法。

class MyViewController: UIViewController {
    let date = ...
    let codeLog = ...
    @IBOutlet var oxygenButton: UIButton!   
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let formatter = DateFormatter()
        formatter.dateFormat = "HH:mm:ss"
        
        let actions: [UIAction] = [2, 4, 6, 8, 10, 15].map { lpm in
            let title = "\(lpm) LPM"
            return UIAction(title: title) { [weak self] _ in
                guard let self = self else { return }
                self.codeLog.append(CodeLog(
                    event: title,
                    time: dateFormatter.string(from: self.date),
                    note: "\(lpm)LPM"
                ))
            }
        }
        
        oxygenButton.menu = UIMenu(
            title: "Oxygen Menu",
            options: .displayInline,
            children: actions
        )
        oxygenButton.showsMenuAsPrimaryAction = true
    }
}
qjp7pelc

qjp7pelc3#

根据this link
如果希望UIMenu立即出现,则需要将showsMenuAsPrimaryAction设置为true,否则长按后菜单将出现。
因此,创建菜单并将其附加到viewDidLoad中的按钮,然后将按钮的showsMenuAsPrimaryAction属性设置为true。

相关问题