MacOS 上列表中的 SwiftUI 键盘导航

2023-12-10

我正在尝试实现一个可以使用箭头键(向上/向下)导航的列表。我已经创建了布局,但现在我不完全理解如何(以及在​​哪里)拦截向上/向下键,以便我可以添加自定义逻辑。我已经尝试过了onMoveCommand with focusable但这不起作用(根本没有触发)

我的代码 - 下面

public var body: some View {
        VStack(spacing: 0.0) {
            VStack {
                HStack(alignment: .center, spacing: 0) {
                    Image(systemName: "command")
                        .resizable()
                        .scaledToFit()
                        .frame(width: 20, height: 20)
                        .padding(.leading, 20)
                        .offset(x: 0, y: 1)
                    TextField("Search Commands", text: $state.commandQuery)
                        .font(.system(size: 20, weight: .light, design: .default))
                        .textFieldStyle(.plain)
                        .onReceive(
                            state.$commandQuery
                                .debounce(for: .seconds(0.1), scheduler: DispatchQueue.main)
                        ) { val in
                            state.fetchMatchingCommands(val: val)
                        }
                    .padding(16)
                    .foregroundColor(Color(.systemGray).opacity(0.85))
                    .background(EffectView(.sidebar, blendingMode: .behindWindow))
                }
            }
            Divider()
            VStack(spacing: 0) {
                List(state.filteredCommands.isEmpty && state.commandQuery.isEmpty ?
                     commandManager.commands : state.filteredCommands, selection: $selectedItem) { command in
                        VStack(alignment: .leading, spacing: 0) {
                            Text(command.title).foregroundColor(Color.white)
                                .padding(EdgeInsets.init(top: 0, leading: 10, bottom: 0, trailing: 0))
                                .frame(height: 10)
                        }.frame(maxWidth: .infinity, maxHeight: 15, alignment: .leading)
                            .listRowBackground(self.selectedItem == command ?
                                               RoundedRectangle(cornerRadius: 5, style: .continuous)
                                .fill(Color(.systemBlue)) :
                                                RoundedRectangle(cornerRadius: 5, style: .continuous)
                                .fill(Color.clear) )

                        .onTapGesture {
                            self.selectedItem = command
                            callHandler(command: command)
                        }.onHover(perform: { _ in self.selectedItem = command })
                    }.listStyle(SidebarListStyle())
            }
        }
        .background(EffectView(.sidebar, blendingMode: .behindWindow))
        .foregroundColor(.gray)
        .edgesIgnoringSafeArea(.vertical)
        .frame(minWidth: 600,
           minHeight: self.state.isShowingCommandsList ? 400 : 28,
           maxHeight: self.state.isShowingCommandsList ? .infinity : 28)
    }

这就是它的样子 - 我想让焦点在找到的列表项之间移动

enter image description here


如果我正确理解你的问题,你想使用箭头键从search TextField,到项目列表,然后使用向上/向下箭头键导航列表。

尝试像此示例代码这样简单的操作,以监视向上/向下箭头键,并采取适当的操作。

调整/调整逻辑以满足您的需求。

import Foundation
import SwiftUI
import AppKit


struct ContentView: View {
    let fruits = ["apples", "pears", "bananas", "apricot", "oranges"]
    @State var selection: Int?
    @State var search = ""
    
    var body: some View {
        VStack {
            VStack {
                HStack(alignment: .center, spacing: 0) {
                    Image(systemName: "command")
                        .resizable()
                        .scaledToFit()
                        .frame(width: 20, height: 20)
                        .padding(.leading, 20)
                        .offset(x: 0, y: 1)
                    TextField("Search", text: $search)
                        .font(.system(size: 20, weight: .light, design: .default))
                        .textFieldStyle(.plain)
                }
            }
            Divider()
            List(selection: $selection) {
                ForEach(fruits.indices, id: \.self) { index in
                    Text(fruits[index]).tag(index)
                }
            }
            .listStyle(.bordered(alternatesRowBackgrounds: true))
        }
        .onAppear {
            NSEvent.addLocalMonitorForEvents(matching: [.keyDown]) { nsevent in
                if selection != nil {
                    if nsevent.keyCode == 125 { // arrow down
                        selection = selection! < fruits.count ? selection! + 1 : 0
                    } else {
                        if nsevent.keyCode == 126 { // arrow up
                            selection = selection! > 1 ? selection! - 1 : 0
                        }
                    }
                } else {
                    selection = 0
                }
                return nsevent
            }
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MacOS 上列表中的 SwiftUI 键盘导航 的相关文章

随机推荐

  • Slickgrid:最终列自动调整大小以使用所有剩余空间

    我正在使用 SlickGrid 并努力寻找一个优雅的解决方案来解决以下问题 所有列在首次渲染时必须具有特定的初始宽度 但之后可以调整大小 调整窗口大小时 最后一列应自动填充剩余的列空间 我见过 使一列填充 SlickGrid 中的剩余空间
  • 使用新的架构更改更新 LinqtoSql 数据库?

    我有一个已发布到市场的 Windows Phone 7 应用程序 我将 Sql CE 与 LinqToSql 一起使用 当应用程序运行时 它会通过连接字符串检查数据库是否存在 如果不存在则创建数据库 using CheckbookDataC
  • 在 Google Apps 脚本中转义正则表达式文字

    我不知道为什么这不起作用 我已经通过我在网上找到的更好的正则表达式工具之一来验证它 并且我之前使用的似乎是转义字符 号使其成为字面 但 Google 脚本一直抱怨 无效量词 第 2 行 这是我的脚本 省略了某些个人详细信息 这是为了清理电子
  • Django - 将额外参数传递给 upload_to 可调用函数

    我知道您可以使用 upload to 参数传递可调用函数来动态更改 Django 模型中的 FileFied ImageField 等 upload to 调用的函数传递了 2 个变量 即未保存在数据库中的文件的实例 instance 和所
  • 将分组平均值添加到数据框中的列[重复]

    这个问题在这里已经有答案了 我想计算数据框中的组平均值 并在包含这些组平均值的原始数据框中创建一个新列 我正在进行重复性研究 我想要新列中插入 单元和通道内测量的平均值 以便我可以将其减去并计算残差 My data gt head myte
  • 如何在 HttpPost 中使用参数

    我正在通过以下方法使用 RESTful Web 服务 POST Consumes application json Path create public void create String str1 String str2 System
  • 定期运行 JavaScript 函数

    我目前正在建立一个网站来托管软件 我想要的是在项目页面中添加循环截图的幻灯片 大约每 5 秒更改一次图像 有没有办法仅使用 JavaScript 在一定时间间隔触发脚本 或者我是否必须采用替代方法来实现我想要的功能 预先感谢您的任何帮助 s
  • Typescript 类型、泛型和抽象类

    我尝试了一种对我来说似乎很奇怪的行为 让我们考虑以下示例 在 Typescript Playground 中测试它 abstract class FooAbstract abstract bar class Foo extends FooA
  • MonoTouch“无法 AOT 程序集”

    我正在使用 MonoTouch 6 2 并且我有一个应用程序可以在模拟器上构建并运行良好 但当我为实际设备构建时 会出现 无法 AOT 程序集 错误 有没有人见过这个 这是编译器的输出 Applications Xcode app Cont
  • 在 Tomcat 上运行 JasperViewer 作为 Web 应用程序的一部分

    我了解到贾斯珀浏览器 默认预览组件贾斯珀报告 is a Swing组件 那么有什么方法可以将其转换或嵌入到Web应用程序中吗 有人说我应该使用Java网络启动 但据我所知这个链接 JWS在客户端计算机上下载并安装应用程序非常有用 但这不是我
  • 如何禁用特定控件的视图状态?

  • jquery 显示 [object object] 而不是数组 [重复]

    这个问题在这里已经有答案了 只是试图在视图中显示我通过 ajax 从控制器获取的数组 但它显示 object Object object Object 而不是数组 请检查我的js文件如下 faq title click function v
  • 如何在 PHP 中循环使用十六进制颜色代码?

    我想要一个数组 其中数组中的每个字段都包含一个颜色代码 array 0 gt 4CFF00 1 gt FFE97F 我希望它能够经历从绿色到黑色的整个颜色范围 绿色 gt 蓝色 gt 深蓝色 gt 紫色 gt 黄色 gt 橙色 gt 红色
  • 前面带有“0”的数字文字[重复]

    这个问题在这里已经有答案了 Using insert 我将值推入Array as myarray 22 33 44 myarray insert 0 02 gt 2 22 33 44 如果执行以下操作 我得到 myarray insert
  • 获取数组中特定项目的索引

    我想检索数组的索引 但我只知道数组中实际值的一部分 例如 我在数组中动态存储作者姓名 author xyz 现在我想找到包含它的数组项的索引 因为我不知道值部分 这个怎么做 您可以使用查找索引 var index Array FindInd
  • javascript 创建日期错误的月份

    使用 Mozilla Firefox Firebug var myDate new Date 2012 9 23 0 0 0 0 myDate 日期 2012 年 10 月 23 日星期二 00 00 00 GMT 0400 东部夏令时间
  • 如何验证机器人是否正在输入信息

    我有一个网络表单 用户填写该表单并将信息发送到服务器并存储在数据库中 我担心机器人可能只是填写表格 而我最终会得到一个充满无用记录的数据库 如何防止机器人填写我的表格 我在想也许类似于 Stackoverflow 的机器人检测 如果它认为你
  • 如何在 Ubuntu 16.04 上使用带有 Python 3.7 的 sqlite3 python 模块的 FTS5 扩展?

    为了测试带有 sqlite3 Python 模块的 FTS5 扩展是否有效 我使用了这个code from 技术进步 import sqlite3 conn sqlite3 connect memory conn execute creat
  • 在javascript中将输入框滚动到光标位置

    我编写了一个简单的 JS 函数 当输入框接收焦点时 它将光标置于输入框内容的末尾 框中最常见的操作是追加 我没有在 IE 中检查过 但是当文本多于可见文本时 即使将光标移动到输入末尾也不会在 Firefox 3 6 中将视图滚动到输入末尾
  • MacOS 上列表中的 SwiftUI 键盘导航

    我正在尝试实现一个可以使用箭头键 向上 向下 导航的列表 我已经创建了布局 但现在我不完全理解如何 以及在 哪里 拦截向上 向下键 以便我可以添加自定义逻辑 我已经尝试过了onMoveCommand with focusable但这不起作用