Команда Key в приложении Catalyst, использующем SwiftUI, непрерывно срабатывает - PullRequest
1 голос
/ 29 марта 2020

Я создаю приложение iOS в SwiftUI и надеюсь запустить его на Ma c также с использованием Catalyst. Я добавил комбинацию клавиш CMD+N, используя UIKeyCommand на главном контроллере хостинга, которая запускает Notification, который слушает моя модель ObservableObject, переключая свойство alert для отображения предупреждения. Вот код:

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, это работает правильно - одно уведомление срабатывает, и предупреждение показывается. Однако в приложении Ma c 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.

1 Ответ

0 голосов
/ 16 апреля 2020

У меня была похожая проблема с созданием нового windows. Я не создавал никаких пользовательских действий, но мое приложение для iPad имело многооконную поддержку, поэтому Command-N просто «работал», когда я создавал приложение ma c.

Единственная проблема заключалась в том, что оно не будет прекратить создавать новые windows. В конце концов я обнаружил, что при переходе со Swift 4 -> 5 я получил неправильный обратный вызов UIApplicationDelegate. Итак, appDidFinishLaunching никогда не вызывался.

Затем я использовал автозаполнение, чтобы получить правильную сигнатуру метода, и это решило мою проблему.

Это была правильная ошибка: func applicationDidFinishLaunching(_ application: UIApplication) {

Я не совсем уверен, почему это привело к созданию окна l oop, но двух дней достаточно, чтобы тратить время на его отслеживание. Надеюсь, это поможет кому-то там.

...