How to set first responder for NSTextView in Swift?
Corrected Answer
In AppKit, you need:
if mainTextField.acceptsFirstResponder {
mainTextField.window?.makeFirstResponder(mainTextField)
}
In this case, it's probably safe to not check acceptsFirstResponder
, but it doesn't hurt either.
Original Answer (UIKit
)
You need to call mainTextField.becomeFirstResponder()
.
How to move cursor when new NSTextView becomes FirstResponder (MacOS)?
I was able to get the desired behaviour by doing this:
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
}
The answer originally comes from here: How to make first responder in SwiftUI macOS
Thanks for all the help!
Send command shortcut to NSTextView's next responder
You can subclass NSTextView
override keyDown
method and call next responder:
import Cocoa
class TextView: NSTextView {
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
}
override func keyDown(with event: NSEvent) {
super.keyDown(with: event)
nextResponder?.keyDown(with: event)
}
}
make NSTextField in NSTableCellView firstResponder()
Don't subclass NSTextField
. You can make the text field in a view based table view first responder right out of the box.
It's pretty easy.
Assuming you know row
and column
(in your example row 0 and column 0) get the table cell view with view(atColumn: 0, row
and make the text field first responder.
let keyView = tableView.view(atColumn: 0, row: 0, makeIfNecessary: false) as! NSTableCellView
view.window!.makeFirstResponder(keyView.textField)
And what is the second outlet for? Just use the standard default textField
.
How to make first responder in SwiftUI macOS
If your MyField
is a NSTextField
the following works. Tested with 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
}
NSTextField keep focus/first responder after NSPopover
Here's my attempt with help from How can one programatically begin a text editing session in a NSTextField? and How can I make my NSTextField NOT highlight its text when the application starts?:
The selected range is saved in textShouldEndEditing
and restored in becomeFirstResponder
. insertText(_:replacementRange:)
starts an editing session.
var savedSelectedRanges: [NSValue]?
override func becomeFirstResponder() -> Bool {
if super.becomeFirstResponder() {
if self.aboutToShowPopover {
if let ranges = self.savedSelectedRanges {
if let fieldEditor = self.currentEditor() as? NSTextView {
fieldEditor.insertText("", replacementRange: NSRange(location: 0, length:0))
fieldEditor.selectedRanges = ranges
}
}
}
return true
}
return false
}
override func textShouldEndEditing(_ textObject: NSText) -> Bool {
if super.textShouldEndEditing(textObject) {
if self.aboutToShowPopover {
let fieldEditor = textObject as! NSTextView
self.savedSelectedRanges = fieldEditor.selectedRanges
return true
}
let s = textObject.string
if s == "2" {
return true
}
}
return false
}
Maybe rename aboutToShowPopover
.
setting first responder on modal sheet
Code snippet pretty much does it all, except the border rect as in an NSTextField.
Force NSSearchField to Begin Editing When It Becomes First Responder
It turns out the key was bringing my application to the forefront.
I was able to give my application the system's focus by calling NSApplication.sharedApplication().activateIgnoringOtherApps(true)
. My NSSearchField, which was already becoming the first responder, can now directly be edited.
NSTextView won't become first responder
To force the first responder for a window, call this:
[[self window] makeFirstResponder:self.customTextContainerView];
(This assumes that everything else necessary for first-responder status is enabled, e.g. the view can't have overridden acceptsFirstResponder
to return NO
.)
Related Topics
Realm: Predicate Returning Lazyfiltercollection - How to Convert to Results<T>
Reading from Txt File in Swift 3
How Is Commoncrypto Used in Swift3
Inner Didset Protection Bizarrely Extends to The Whole Class
Passing Parameters with #Selector
Swift: Rsa Encrypt a String with a Specific Private Key
In App Purchase on MAC Catalyst Not Working
Swift Compiler Crashes on Associatedtype in @Objc Protocol
Difference Between Userdefaults() and Userdefaults.Standard
Why Do I Have to Explicitly Unwrap My String in This Case
How to Call Completionhandler for Performfetchwithcompletionhandler in Swift
Cannot Convert [Int] to [Int] in Generic Implementation
Sbdata Is Wrong When Sbvalue Comes from a Swift Dictionary
+' Is Deprecated: Mixed-Type Addition Is Deprecated in Swift 3.1