使用 SwiftUI 的 Catalyst 应用程序中的键盘命令连续触发
Posted
技术标签:
【中文标题】使用 SwiftUI 的 Catalyst 应用程序中的键盘命令连续触发【英文标题】:Key command in Catalyst app using SwiftUI continuously fires 【发布时间】:2020-03-29 18:06:30 【问题描述】:我正在使用 SwiftUI 构建一个 ios 应用程序,并希望也可以使用 Catalyst 在 Mac 上运行它。我在主主机控制器上使用UIKeyCommand
添加了键盘快捷键CMD+N
,它会触发我的 ObservableObject 模型监听的Notification
,切换警报属性以显示警报。代码如下:
class KeyCommandHostingController<Content: View>: UIHostingController<Content>
override var keyCommands: [UIKeyCommand]?
[
UIKeyCommand(title: "New Game", action: #selector(postNewGame), input: "n", modifierFlags: .command)
]
@objc func postNewGame()
print("postNewGame called")
NotificationCenter.default.post(name: .newGameRequested, object: nil)
public extension Notification.Name
static let newGameRequested = Notification.Name(rawValue: "newGameRequested")
class Model: ObservableObject
@Published var presentAlert = false
var cancellables = Set<AnyCancellable>()
init()
NotificationCenter.default
.publisher(for: .newGameRequested)
.sink [unowned self] _ in
self.presentAlert.toggle()
print("new game requested")
.store(in: &cancellables)
struct ContentView: View
@ObservedObject var model: Model
var body: some View
Text("Hello, World!")
.alert(isPresented: $model.presentAlert)
Alert(title: Text("New Game"),
message: Text("Are you sure you want to start a new game? The current game will be recorded as a loss."),
primaryButton: Alert.Button.destructive(Text("New Game"))
print("New Game selected")
,
secondaryButton: Alert.Button.cancel()
)
当我在 iPhone 或 iPad 模拟器中执行键盘命令时,它的行为正确 - 触发一个通知,并显示警报。但是,在 Mac Catalyst 应用程序中,按一次键盘快捷键会导致通知被无休止地触发,这会导致应用程序尝试一遍又一遍地无休止地显示警报。控制台输出证实了这一点,并带有以下无限输出(截断):
new game requested
postNewGame called
new game requested
postNewGame called
new game requested
postNewGame called
new game requested
2020-03-29 14:04:11.179475-0400 AlertMadness[1332:29452] Warning: Attempt to present <SwiftUI.PlatformAlertController: 0x10192de00> on <_TtGC12AlertMadness27KeyCommandHostingControllerVS_11ContentView_: 0x10310bcf0> while a presentation is in progress!
postNewGame called
new game requested
postNewGame called
new game requested
postNewGame called
new game requested
postNewGame called
new game requested
2020-03-29 14:04:11.595161-0400 AlertMadness[1332:29452] Warning: Attempt to present <SwiftUI.PlatformAlertController: 0x10195ca00> on <_TtGC12AlertMadness27KeyCommandHostingControllerVS_11ContentView_: 0x10310bcf0> while a presentation is in progress!
(etc...)
是我做错了什么,还是 Catalyst/SwiftUI 中的错误?使用 Xcode 11.4 和 macOS 10.15.4。
【问题讨论】:
我遇到了类似的问题。我没有添加任何用于处理键盘输入的代码,但我添加了多窗口支持,并且我的催化剂应用程序在按下 Command-n 后继续创建新窗口?还有 xcode 11.4 和 10.15.4 macOS 对于它的价值,我后来发现将 UIKeyCommand 放在 AppDelegate 的buildMenu(with:)
方法以及 UIHostingController 的 keyCommands
属性中可以防止发生无限触发。这有点重复,但它帮助了我。
谢谢,我会试试的。很高兴听到至少我不是唯一遇到这种情况的人。
我也遇到了同样的问题,一直没找到原因,一直在调用方法-.-
@UberJason 自那以后有什么更新吗?我已提交反馈。
【参考方案1】:
我在创建新窗口时遇到了类似的问题。我没有创建任何自定义操作,但我的 iPad 应用程序支持多窗口,所以当我构建 mac 应用程序时,Command-N 只是“工作”。
唯一的问题是它不会停止创建新窗口。最终我发现在我从 Swift 4 -> 5 的迁移中,我得到了一个不正确的 UIApplicationDelegate
回调。所以,appDidFinishLaunching
从未被调用过。
然后我使用自动完成来获得正确的方法签名并解决了我的问题。
这是正确的:func applicationDidFinishLaunching(_ application: UIApplication)
我不确定为什么会导致窗口创建循环,但是两天时间足以浪费在跟踪它上。希望能帮助到那里的人。
【讨论】:
以上是关于使用 SwiftUI 的 Catalyst 应用程序中的键盘命令连续触发的主要内容,如果未能解决你的问题,请参考以下文章
Big Sur 在 SwiftUI Catalyst 中的点击问题