当新的 NSTextView 成为 FirstResponder (MacOS) 时如何移动光标?
How to move cursor when new NSTextView becomes FirstResponder (MacOS)?
每次用户按下回车键,都会创建一个新的 NSTextView。这工作正常,新的 NSTextView 成为第一响应者,这是我的目标。但是,尽管它是第一响应者,但光标不会移动到新的 NSTextView 中。
下面是我的代码:
func makeNSView(context: NSViewRepresentableContext<TextView>) -> TextView.NSViewType {
let textView = NSTextView()
textView.textContainer?.lineFragmentPadding = 10
textView.textContainerInset = .zero
textView.font = NSFont.systemFont(ofSize: 12)
textView.becomeFirstResponder()
//NSApp.activate(ignoringOtherApps: true) ----> doesn't make difference but is supposed to help switch cursor
print("\(textView) is first responder") //proof that the first responder is shifting, but the cursor does not move with it for some reason
return textView
}
我尝试按照不同答案的建议使用这一行:
NSApp.activate(ignoringOtherApps: true)
但是,这没有任何区别。我也试过在选定范围内插入文本,但它不会在显示的任何 NSTextView 中插入文本,无论它们是否是第一响应者。
有哪些方法可以将光标移动到不同的 NSTextView(最好是 First Responder)?
如果需要更多信息,请告诉我。
正如 Warren Burton 在评论中提到的那样,在您试图使其成为第一响应者时,您还没有将新视图添加到 window 的视图层次结构中。那不行。
此外,调用 becomeFirstResponder()
不会 使接收者成为第一响应者。 (这与 UIKit 不同。)事实上,您永远不应该在 macOS 上调用 becomeFirstResponder()
(除非转发到覆盖中的超类)。 documentation 明确指出:
Use the NSWindow makeFirstResponder(_:)
method, not this method, to make an object the first responder. Never invoke this method directly.
(强调已添加。)becomeFirstResponder()
由 Cocoa 调用以通知视图(或其他响应者)它已成为第一响应者。它不会导致更改,它会通知更改。
因此,一旦将视图添加到 window 的视图层次结构中,调用 textView.window.makeFirstResponder(textView)
.
我能够通过这样做获得所需的行为:
func makeNSView(context: NSViewRepresentableContext<TextView>) -> TextView.NSViewType {
let textView = NSTextView()
textView.textContainer?.lineFragmentPadding = 10
textView.textContainerInset = .zero
textView.font = NSFont.systemFont(ofSize: 12)
DispatchQueue.main.async {textView.window?.makeFirstResponder(textView)
textView.setSelectedRange(NSMakeRange(0, 0)) }
print("\(textView) is first responder") //proof that the first responder is shifting, but the cursor does not for some reason
return textView
}
原答案出自这里:
感谢大家的帮助!
每次用户按下回车键,都会创建一个新的 NSTextView。这工作正常,新的 NSTextView 成为第一响应者,这是我的目标。但是,尽管它是第一响应者,但光标不会移动到新的 NSTextView 中。
下面是我的代码:
func makeNSView(context: NSViewRepresentableContext<TextView>) -> TextView.NSViewType {
let textView = NSTextView()
textView.textContainer?.lineFragmentPadding = 10
textView.textContainerInset = .zero
textView.font = NSFont.systemFont(ofSize: 12)
textView.becomeFirstResponder()
//NSApp.activate(ignoringOtherApps: true) ----> doesn't make difference but is supposed to help switch cursor
print("\(textView) is first responder") //proof that the first responder is shifting, but the cursor does not move with it for some reason
return textView
}
我尝试按照不同答案的建议使用这一行:
NSApp.activate(ignoringOtherApps: true)
但是,这没有任何区别。我也试过在选定范围内插入文本,但它不会在显示的任何 NSTextView 中插入文本,无论它们是否是第一响应者。
有哪些方法可以将光标移动到不同的 NSTextView(最好是 First Responder)?
如果需要更多信息,请告诉我。
正如 Warren Burton 在评论中提到的那样,在您试图使其成为第一响应者时,您还没有将新视图添加到 window 的视图层次结构中。那不行。
此外,调用 becomeFirstResponder()
不会 使接收者成为第一响应者。 (这与 UIKit 不同。)事实上,您永远不应该在 macOS 上调用 becomeFirstResponder()
(除非转发到覆盖中的超类)。 documentation 明确指出:
Use the NSWindow
makeFirstResponder(_:)
method, not this method, to make an object the first responder. Never invoke this method directly.
(强调已添加。)becomeFirstResponder()
由 Cocoa 调用以通知视图(或其他响应者)它已成为第一响应者。它不会导致更改,它会通知更改。
因此,一旦将视图添加到 window 的视图层次结构中,调用 textView.window.makeFirstResponder(textView)
.
我能够通过这样做获得所需的行为:
func makeNSView(context: NSViewRepresentableContext<TextView>) -> TextView.NSViewType {
let textView = NSTextView()
textView.textContainer?.lineFragmentPadding = 10
textView.textContainerInset = .zero
textView.font = NSFont.systemFont(ofSize: 12)
DispatchQueue.main.async {textView.window?.makeFirstResponder(textView)
textView.setSelectedRange(NSMakeRange(0, 0)) }
print("\(textView) is first responder") //proof that the first responder is shifting, but the cursor does not for some reason
return textView
}
原答案出自这里:
感谢大家的帮助!