Ios Catalyst应用程序中使用SwiftUI的按键命令持续激发

Ios Catalyst应用程序中使用SwiftUI的按键命令持续激发,ios,swiftui,mac-catalyst,Ios,Swiftui,Mac Catalyst,我正在SwiftUI上构建一个iOS应用程序,并希望使用Catalyst在Mac上运行它。我在主宿主控制器上使用UIKeyCommand添加了一个键盘快捷键CMD+N,它触发我的ObserveObject模型侦听的通知,切换警报属性以显示警报。代码如下: class KeyCommandHostingController<Content: View>: UIHostingController<Content> { override var keyCommands:

我正在SwiftUI上构建一个iOS应用程序,并希望使用Catalyst在Mac上运行它。我在主宿主控制器上使用
UIKeyCommand
添加了一个键盘快捷键
CMD+N
,它触发我的ObserveObject模型侦听的
通知,切换警报属性以显示警报。代码如下:

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()
                )
            }
    }
}
class KeyCommandHostingController:UIHostingController{
覆盖var keyCommands:[UIKeyCommand]{
[
UIKeyCommand(标题:“新游戏”,操作:#选择器(postNewGame),输入:“n”,修饰符标签:。命令)
]
}
@objc func postNewGame(){
打印(“称为postNewGame”)
NotificationCenter.default.post(名称:.newGameRequested,对象:nil)
}
}
公共扩展通知。名称{
静态let newGameRequested=Notification.Name(rawValue:“newGameRequested”)
}
类模型:ObservieObject{
@已发布的var presentAlert=false
var cancelables=Set()
init(){
NotificationCenter.default
.publisher(用于:.newGameRequested)
.sink{[unowned self]\uuin
self.presentAlert.toggle()
打印(“请求新游戏”)
}
.store(在:&可取消项中)
}
}
结构ContentView:View{
@观测对象var模型:模型
var body:一些观点{
文本(“你好,世界!”)
.alert(显示:$model.presentAlert){
警报(标题:文本(“新游戏”),
消息:文本(“您确定要开始新游戏吗?当前游戏将记录为失败。”),
primaryButton:Alert.Button.destructive(文本(“新游戏”)){
打印(“选择新游戏”)
},
secondaryButton:Alert.Button.cancel()
)
}
}
}
当我在iPhone或iPad模拟器中执行键盘命令时,它的行为是正确的——触发一个通知,并显示警报。但是,在Mac Catalyst应用程序中,一次按下键盘快捷键会导致无休止地触发通知,从而导致应用程序尝试无休止地反复显示警报。控制台输出通过以下无限输出(截取)进行确认:

请求新游戏
后新游戏
新游戏请求
后新游戏
新游戏请求
后新游戏
新游戏请求
2020-03-29 14:04:11.179475-0400警惕性疯狂[1332:29452]警告:在演示过程中尝试打开演示文稿!
后新游戏
新游戏请求
后新游戏
新游戏请求
后新游戏
新游戏请求
后新游戏
新游戏请求
2020-03-29 14:04:11.595161-0400警报疯狂[1332:29452]警告:在演示过程中尝试打开演示文稿!
(等等……)

我是否做错了什么,或者这是Catalyst/SwiftUI中的错误?使用Xcode 11.4和macOS 10.15.4时,我在创建新窗口时遇到了类似的问题。我没有创建任何自定义操作,但我的iPad应用程序支持多窗口,因此在我构建mac应用程序时,Command-N只是“起作用”

唯一的问题是它不会停止创建新窗口。最终我发现,在从Swift 4->5迁移的过程中,我遇到了一个错误的
UIApplicationLegate
回调。因此,
appDidFinishLaunching
从未被调用

然后,我使用autocomplete获得正确的方法签名,这解决了我的问题

这是正确的:
func applicationdifinishlaunching(application:UIApplication){


我不太清楚为什么会出现窗口创建循环,但两天的时间足够花在跟踪上了。希望这对其他人有所帮助。

我在创建新窗口时遇到了类似的问题。我没有创建任何自定义操作,但我的iPad应用程序支持多窗口,所以Command-N只是“起作用”当我构建mac应用程序时

唯一的问题是它不会停止创建新窗口。最终我发现,在从Swift 4->5迁移的过程中,我遇到了一个错误的
UIApplicationLegate
回调。因此,
appDidFinishLaunching
从未被调用

然后,我使用autocomplete获得正确的方法签名,这解决了我的问题

这是正确的:
func applicationdifinishlaunching(application:UIApplication){


我不太清楚为什么会出现窗口创建循环,但两天的时间足够花在跟踪上了。希望这对其他人有所帮助。

我也有类似的问题。我没有添加任何处理键盘输入的代码,但我添加了多窗口支持,我的catalyst应用程序只是在点击Command-n后继续创建新窗口?同样是xcode 11.4和10.15.4 MacOS。我后来发现,将UIKeyCommand放入AppDelegate的
buildMenu(带:)
方法以及UIHostingController的
keyCommands
属性中的方法可以防止无限触发器的发生。它有点重复,但对我有帮助。谢谢,我会尝试一下。很高兴听到我不是唯一一个遇到这种情况的人。我遇到了同样的问题,从未找到原因,并不断调用方法-。-@UberJason此后有没有更新?我已经提交了一个反馈。我也遇到了类似的问题。我没有添加任何处理键盘输入的代码,但我添加了多窗口支持,我的catalyst应用程序在点击Command-n后一直在创建新的窗口?还有xcode 11.4和10.15.4 MacOS。我后来发现,将UIKeyCommand放在Ap中是值得的pDelegate的
buildMenu(with:)
方法以及UIHostingController的
keycomands
属性防止了无限触发器的发生。它有点重复,但对我有帮助。谢谢,我会尝试一下。很高兴听到我不是唯一一个经历这种情况的人
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...)