我遇到了一个简单的SwiftUI视图包含TextField的问题.

如果ViewSwiftUI App > Scene > WindowGroup中,视图中的TextField将按照预期运行,我可以使用TextField中的快捷方式(如Command+a)来 Select TextFieldcopy/past中的所有文本.

如果View在通过编程创建的NSWindow中被设置为contentViewNSHostingView中,我的TextField不接受使用Command键的快捷键.我仍然可以按CTRL键输入文本或使用快捷键,但按Command键时铃声响起,什么也没有发生.

以下是工作版本的代码:

import Foundation
import SwiftUI

struct MyView: View {
    @State var text = ""
    
    var body: some View {
        TextField("My textfield", text: $text).padding()
    }
}

@main
struct TestCoreDataSwiftApp: App {
    var body: some Scene {
        WindowGroup {
            MyView()
        }
    }
}

以下是不工作版本的代码:

import Foundation
import Cocoa
import SwiftUI

let app = NSApplication.shared
let delegate = AppDelegate()
app.delegate = delegate

_ = NSApplicationMain(CommandLine.argc, CommandLine.unsafeArgv)

struct MyView: View {
    @State var text = ""
    
    var body: some View {
        TextField("My textfield", text: $text).padding()
    }
}

class AppDelegate: NSObject, NSApplicationDelegate {
    private var window: NSWindow?
    
    func applicationDidFinishLaunching(_ aNotification: Notification) {
        window = NSWindow()
        window?.contentView = NSHostingView(rootView: MyView())
        window?.makeKeyAndOrderFront(self)
        window?.makeFirstResponder(nil)
    }
}

[EDIT]

我做了更多的测试.

如果一切都是使用界面生成器创建的(将NSTextField拖放到NSView中),它也会按预期工作.

如果我们以编程方式创建NSView并添加NSTextField,这里同样不起作用:

    // Not working code
    func applicationDidFinishLaunching(_ aNotification: Notification) 
    {
        NSApplication.shared.activate(ignoringOtherApps: true)
        window = NSWindow(contentRect: NSRect(x: 400, y: 400, width: 400, height: 100), styleMask: [.miniaturizable, .closable, .resizable, .titled], backing: .buffered, defer: false)
        window.center()
        window.title = "Title"
        window.contentView = NSView(frame: NSRect(x: 0, y: 0, width: 300, height: 300))
        let textField = NSTextField(frame: NSRect(x: 0, y: 0, width: 250, height: 60))
        window.contentView?.addSubview(textField)
        window.makeKeyAndOrderFront(nil)
    }

我怀疑它与福克斯或firstResponder有关,但我无法让它发挥作用.欢迎任何帮助.谢谢!

推荐答案

In fact, those shortcuts are related to the application menu (NSMenu). They don't exist by default without it.
So, if the application doesn't have the Edit menu where all this shortcuts are defined, they are simply not available in the TextField.

在各种情况下,它都有效,这是因为默认IB项目和SWIFT UI项目都默认添加了此菜单.

在这种情况下,这不是firstResponder的问题.

为了实现这一点,解决方案是:

  1. 在应用程序中添加带有快捷方式的Edit菜单(如果菜单被隐藏则不起作用).
  2. 按照Vonc的建议以编程方式管理快捷键
class NSHostingViewShortcuts<Content>: NSHostingView<Content> where Content : View {
    override func performKeyEquivalent(with event: NSEvent) -> Bool {
        if event.modifierFlags.contains(.command) {
            let shortcuts = [
                "a": #selector(NSStandardKeyBindingResponding.selectAll(_:)),
                "x": #selector(NSText.cut(_:)),
                "c": #selector(NSText.copy(_:)),
                "v": #selector(NSText.paste(_:))
            ]
            if event.characters != nil && shortcuts[event.characters!] != nil {
                NSApp.sendAction(shortcuts[event.characters!]!, to: nil, from: nil)
                return true
            }
        }
        
        return super.performKeyEquivalent(with: event)
    }
}

Swift相关问答推荐

什么是Swift Concurrency中任务组的正常退出

同步问题,发送Api Call之前未设置idToken

如何取消正在视图修改器中运行的任务

如何将EnvironmentObject从UIKit视图控制器传递到SwiftUI视图

ARRaycast Query和前置摄像头(ARFaceTrackingConfiguration)

如何在SwiftUI中做出适当的曲线?

与视图交互使工具栏&;标题消失

SwiftUI 组合问题:通过 AppEventsManager 在 ViewModel 之间共享数据

数组中某些元素的总和

如何让飞机与 RealityKit 中的物体相撞

deinitialize() 与 deallocate()

Swift-SceneKit-无法从art.scnassets加载.scn文件

在主要参与者中启动分离任务和调用非隔离函数之间的区别

如何使 SwiftUI Picker 换行文本

临时添加到视图层次 struct 后,Weak view引用不会被释放

无法分配给属性:self 是不可变的,我知道如何修复但需要理解

UICollectionView 自定义单元格在 Swift 中填充宽度

协议扩展中的where self是什么

Void 函数中意外的非 Void 返回值 (Swift 2.0)

我可以让#selector 引用 Swift 中的闭包吗?