Ios Catalyst应用程序中使用SwiftUI的按键命令持续激发
我正在SwiftUI上构建一个iOS应用程序,并希望使用Catalyst在Mac上运行它。我在主宿主控制器上使用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:
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...)