Swift:如何为#selector传递参数?解决传参报错问题
你遇到的错误核心原因是:#selector只能引用符合Objective-C签名的方法,不能直接在选择器里传递参数(比如你写的#selector(setDevice(deviceId: device.uniqueID))这种写法完全不合法)。另外UIKeyCommand的action方法有固定签名要求,必须接收一个UIKeyCommand类型的sender参数。
解决步骤
- 调整
setDevice方法的签名,让它接收sender参数,从sender的userInfo中提取设备ID - 创建
UIKeyCommand时,通过propertyList(对应userInfo)传递uniqueID - 修复循环中重复创建菜单的问题(原代码会在每次循环插入新菜单,导致重复添加)
修正后的完整代码
override func buildMenu(with builder: UIMenuBuilder) { super.buildMenu(with: builder) // 先收集所有设备对应的菜单项 var menuItems: [UIKeyCommand] = [] ReactNativeMidiKit().midiManager.endpoints.outputs.forEach { device in let menuItem = UIKeyCommand( title: device.name, action: #selector(setDevice(_:)), input: nil, modifierFlags: [], propertyList: ["deviceId": device.uniqueID] ) menuItem.state = device.uniqueID == selectedUniqueID ? .on : .off menuItems.append(menuItem) } // 一次性创建顶级菜单并插入 let midiDeviceMenu = UIMenu(title: "Midi Devices", children: menuItems) builder.insertSibling(midiDeviceMenu, afterMenu: .application) } @objc func setDevice(_ sender: UIKeyCommand) { guard let deviceId = sender.userInfo?["deviceId"] else { return } print(deviceId) // 这里添加设备切换的业务逻辑 selectedUniqueID = deviceId as? String // 假设selectedUniqueID是你存储选中ID的变量 UIMenuSystem.main.setNeedsRebuild() }
关键改动说明
- 方法签名调整:把原
setDevice(deviceId: Any)改成@objc func setDevice(_ sender: UIKeyCommand),完全符合UIKeyCommand的action方法要求 - 参数传递方式:通过UIKeyCommand的
propertyList字段存入设备ID,在方法内从sender.userInfo中取出 - 菜单创建逻辑优化:原代码在循环中重复创建并插入顶级菜单,现在先收集所有菜单项,再一次性创建菜单,避免重复添加
内容的提问来源于stack exchange,提问作者Jerry Seigle
相关产品推荐
相关产品推荐

