SwiftUI iOS - 如何使用捕获的硬件按键事件

Posted

技术标签:

【中文标题】SwiftUI iOS - 如何使用捕获的硬件按键事件【英文标题】:SwiftUI iOS - how to use captured hardware key events 【发布时间】:2020-04-12 20:21:43 【问题描述】:

如何在 SwiftUI 中使用按键信息? 我尝试使用@EnvironmentObject 与我的 SwiftUI 共享密钥,但每次 sendKeybKey 崩溃时我都会遇到:线程 1:致命错误:未找到 UserData 类型的 ObservableObject。 UserData 的 View.environmentObject(_:) 作为该视图的祖先可能会丢失。 在 .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 ?? "")")

在场景代理中

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

和用户数据:

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

我的 SwiftUI 视图

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)

有人想快速帮助新手吗?

谢谢!

瓦尔德玛

【问题讨论】:

您能告诉我们您是如何定义 myList 的吗? @Chris My View myList 非常简单。我在我的问题中添加了 sn-p 【参考方案1】:

你不需要在控制器中@EnvironmentObjectUserData是一个引用类型,所以你可以直接在视图和控制器中注入相同的对象。

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

【讨论】:

非常感谢您的帮助。它工作得很好。我为 userData 添加了 Class KeyTestController 初始化程序以防止出现错误“Class 'KeyTestController' has no initializers”:var userData = UserData()

以上是关于SwiftUI iOS - 如何使用捕获的硬件按键事件的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI捕获键盘提交动作在iOS15之前和之后的兼容实现

响应 SwiftUI 中的按键事件

jQuery:如何在文本框中捕获 TAB 按键

如何在不使用输入元素的情况下捕获 Vuejs 中的任何按键事件

SwiftUI 从另一个视图中捕获 Picker 值

如何捕获 Enter 按键? [复制]