如何在 SwiftUI macOS 中成为第一响应者
How to make first responder in SwiftUI macOS
我正在尝试让我的 textField(NSViewRepresentable
包装 NSTextField
)在出现时成为第一响应者。我在这个 中测试了很多答案,但它们要么不起作用:
func updateNSView(_ nsView: MyField, context: Context) {
if some_condition {
print(nsViews.becomeFirstResponder()) // returns false
negate_condition()
}
...
}
或者它与日志一起崩溃 (=== AttributeGraph: cycle detected through attribute 43 ===)
:
func updateNSView(_ nsViews: MyField, context: Context) {
if some_condition {
Window.thisWindow?.makeFirstResponder(nsViews)
negate_condition()
}
...
}
我想要实现的是:
@State var fieldActive: Bool
body: some View {
MyField(...).onAppear { /*makeFirstResponder if fieldActive == true*/ }
}
有人可以帮我解决这个问题吗?非常感谢!
如果您的 MyField
是 NSTextField
以下作品。使用 Xcode 11.4 / macOS 10.15.4
测试
func makeNSView(context: Context) -> MyField {
let view = MyField()
// ... other properties set up here
// wait for next cycle, so field be already in window
DispatchQueue.main.async {
view.window?.makeFirstResponder(view)
}
return view
}
@Asperi 提供了一个有效的方法,我找到了另一条通往答案的道路。我使用 SwiftUI-Introspect library 完成了 SwiftUI TextField 的工作(没有包装 NSTextField),这里是代码:
struct SearchBar {
@Binding var shouldActivate: Bool
var body: some View {
TextField("", text: text)
.textFieldStyle(PlainTextFieldStyle())
.introspectTextField { textField in
if self.shouldActivate {
textField.becomeFirstResponder()
self.shouldActivate = false
}
textField.focusRingType = .none
}
}
我正在尝试让我的 textField(NSViewRepresentable
包装 NSTextField
)在出现时成为第一响应者。我在这个
func updateNSView(_ nsView: MyField, context: Context) {
if some_condition {
print(nsViews.becomeFirstResponder()) // returns false
negate_condition()
}
...
}
或者它与日志一起崩溃 (=== AttributeGraph: cycle detected through attribute 43 ===)
:
func updateNSView(_ nsViews: MyField, context: Context) {
if some_condition {
Window.thisWindow?.makeFirstResponder(nsViews)
negate_condition()
}
...
}
我想要实现的是:
@State var fieldActive: Bool
body: some View {
MyField(...).onAppear { /*makeFirstResponder if fieldActive == true*/ }
}
有人可以帮我解决这个问题吗?非常感谢!
如果您的 MyField
是 NSTextField
以下作品。使用 Xcode 11.4 / macOS 10.15.4
func makeNSView(context: Context) -> MyField {
let view = MyField()
// ... other properties set up here
// wait for next cycle, so field be already in window
DispatchQueue.main.async {
view.window?.makeFirstResponder(view)
}
return view
}
@Asperi 提供了一个有效的方法,我找到了另一条通往答案的道路。我使用 SwiftUI-Introspect library 完成了 SwiftUI TextField 的工作(没有包装 NSTextField),这里是代码:
struct SearchBar {
@Binding var shouldActivate: Bool
var body: some View {
TextField("", text: text)
.textFieldStyle(PlainTextFieldStyle())
.introspectTextField { textField in
if self.shouldActivate {
textField.becomeFirstResponder()
self.shouldActivate = false
}
textField.focusRingType = .none
}
}