SwiftUI iOS - как использовать захваченные события аппаратного ключа - PullRequest
1 голос
/ 12 апреля 2020

Как я могу использовать информацию о нажатой клавише в моем SwiftUI? Я пытаюсь использовать @EnvironmentObject для обмена ключами с моим SwiftUI, но я получаю каждый раз, когда cra sh в sendKeybKey: Поток 1: Неустранимая ошибка: Обнаруженный объект ObservableObject типа UserData не найден. View.environmentObject (_ :) для UserData может отсутствовать как предок этого представления. В .environmentObject уже используется в SceneDelegate, но был не прав? Мой код:

class KeyTestController<Content>: UIHostingController<Content> where Content: View {
@EnvironmentObject var userData: UserData
override func becomeFirstResponder() -> Bool {
        true
}
override var keyCommands: [UIKeyCommand]? {
        var keys = [UIKeyCommand]()

        for num in "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!\r" {
        keys.append(
                    UIKeyCommand(
                                    input:String(num),
                                    modifierFlags: [],
                                    action:
                                    #selector(sendKeybKey)
                                )
                    )
    }
    return keys
}
@objc func sendKeybKey(_ sender: UIKeyCommand) {
        userData.collectChar = sender.input ?? ""
        print(">>> test was pressed \(sender.input ?? "")")
}

}

В SceneDelegate

 if let windowScene = scene as? UIWindowScene {
    let window = UIWindow(windowScene: windowScene)
    window.rootViewController = KeyTestController/*UIHostingController*/(
        rootView: myList()
        .environmentObject(UserData())
    )
    self.window = window
    window.makeKeyAndVisible()
}

и UserData:

    final class UserData: ObservableObject  {
    @Published var datasetUIIdata: [DatasetUII] = []
    @Published var collectChar : String = ""
    @Published var collectText : String = ""
}

My SwiftUI View

struct myList: View {
@EnvironmentObject var userData: UserData

var body: some View {
    VStack {
        HStack {
                Text("Key\(userData.collectChar)").font(.largeTitle)
            }
        .padding()
        List {
            ForEach(userData.datasetUIIdata, id: \.self) { (item) in
                Text(item.userName)
            }
            .onDelete(perform: delete)
        }
        .padding()
    }
}
func delete(at offsets: IndexSet) {
    userData.datasetUIIdata.remove(atOffsets: offsets)
}

}

Всем, кто хочет быстро помочь новичку ie?

Спасибо!

Вальдемар

1 Ответ

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

Вам не нужно @EnvironmentObject в контроллере, UserData является ссылочным типом, поэтому вы можете вводить один и тот же объект непосредственно в поле зрения и в контроллере.

class KeyTestController<Content>: UIHostingController<Content> where Content: View {
      var userData: UserData

, поэтому создание будет ниже

 if let windowScene = scene as? UIWindowScene {
    let window = UIWindow(windowScene: windowScene)

    let userData = UserData()
    let contentView = myList().environmentObject(userData)      // in view !!

    let controller = KeyTestController(rootView: contentView)
    controller.userData = userData                              // in controller !!

    window.rootViewController = controller
...