I am trying to make a search autocomplete in my macOS application:
I have a window with a NSTextField. When value changes, I display an NSPopover which contains NSOutlineView and the list is updated as the user is typing text.
The user can select a result in the NSOutlineView then.
But, if I make NSOutlineView enabled to be able to click on a result, the NSTextField looses focus when NSPopover opens.
If I set isEnabled to false for the NSOutlineView, NSTextField keeps focus but I can't select a result in the list.
Do you have any idea to keep focus on NSTextField without disable NSOutlineView ?
Thank you.
I have found a solution:
Before NSPopover.show(), I store the current textField selected range:
let range = textField.currentEditor()?.selectedRange
And after:
textField.selectText(self)
textField.currentEditor()?.selectedRange = range ?? NSMakeRange(0, 0)
If I call selectText() without setting the selected range, it will select all text.
Moreover, save the selected range keeps cursor position.
Related
I have a view based NSTableView with some labels in my customized and subclassed view. One of the label should be editable, so therefore I set this NSTextField to editable.
But now I have two problems, I can't solve:
1) If I move the mouse over the editable NSTextField, the cursor don't change to the IBeamCursor (the edit cursor).
2) I need to double click at the label, to be able to edit. I want to have a single click. I found some solutions for this problem here at stackoverflow, the best one is to override the acceptsFirstResponder to return always true, but then, clicking at the NSTextField selects the whole text instead of placing the cursor at the clicked position.
Sorry... this is a duplicate. I found this:
NSTableView - select row and respond to mouse events immediately
You have to subclass NSTableView. My swift code:
class TableViewEditing: NSTableView {
...
override func validateProposedFirstResponder(responder: NSResponder, forEvent event: NSEvent?) -> Bool {
return true
}
}
EDIT:
Just one disadvantage: Sometimes entering the edit mode, it seems that the text is just shortly selected and deselected. But you can see, that this is a cocoa problem, it's the same for example in Apple reminders app.
I have a NSTextField and Label whose value is bind to same NSString in the view Controller
The problem here is the label only gets updated when I press Tab.
How do I make it continuous, so that what ever I type in the text box gets reflected in the label immediately?
As of now I am using -(void)controlTextDidChange:(NSNotification *)obj; selector, but I am expecting a binding only solution.
Select the relevant NSTextField in Interface Builder, then navigate to the Bindings Inspector. You need to make sure Continuously Updates Value is checked:
I'm working on an app that presents an NSPopover containing a number of NSTextFields. While I can tab between these fields as I expect, the popover is selecting a particular text field to be in the editing state when it appears, and it's not the field I want to edit; I'd like to be able to define which text field is editing on popover appearance programmatically (or in Interface Builder). How can I do this?
I've set up the appropriate key view loop by connecting IB outlets for all the various text fields involved, and I've hooked up the popover's nextResponder property to the text field I want to edit first, but that doesn't seem to have an effect - the popover will still select its preferred text field instead of mine. The Window Programming Guide suggests that I set the initialFirstResponder outlet of the window to the view I want selected, but an NSPopover is not an NSWindow and has no initialFirstResponder property (unless I'm missing something obvious).
Is there any way to specify which NSTextField I want to be editing when an NSPopover appears?
I think you said you tried using -makeFirstResponder: and passing the text field. This will set the window's firstResponder, but that's not the same as initialFirstResponder and the window must have initialFirstResponder set to something other than nil in order to respect the key view loop. (Source) A slight tweak to what you tried worked for me:
- (void)popoverWillShow:(NSNotification *)notification
{
// Set the window's initialFirstResponder so that the key view loop isn't auto-recalculated.
[[myField window] setInitialFirstResponder:myField];
}
I think you can make this work by setting all the text field's that you don't want to have focus to "selectable" instead of "Editable" in IB, this should leave the one text field you want to start with as the first responder. Then, in your popoverDidShow: method, set them all back to editable, and you should be able to tab between them as usual.
Have a borderless window over NSTextField with a NSButton in that window. canBecomeKeyView returns YES for this NSButton. I want to be able to emulate setNextKeyView for this NSButton to be the next focus holder after NSTextField. The borderless window is the child window of the main window. The NSTextField resides on main window. What is the proper way of doing this thing?
I experienced the same problem.
In interface builder I had a window with an NSTextField and an NSButton. I want to be able to tab between them. I did what I thought was correct:
Set the intialFirstResponser for the NSWindow to be my NSTextField
Set the NSTextField nextKeyView to be the NSButton
Set the NSButton nextKeyView to be my NSTextField
But this was not working as expected.
It Turns out that in the Apple > System Preferences > Keyboard there is a setting that allows you to press Tab to move keyboard focus between:
Text boxes and lists only
All controls
The first option is set by default. Once changed to All controls everything worked as expected.
I have a window with two columns of fields. On the left, there is an NSTableView and an NSTokenField, and on the right, there are two NSTextFields. I want the tab order to go down the left, then down the right. (So the order should be NSTableView, NSTokenField, NSTextField, NSTextField in my window.) However, Cocoa appears to be determining its own preferred order, going from the top to the bottom. The NSTokenField is positioned lower in the window than any other control, so it will always tab from NSTableView, to the right NSTextFields, then back to the bottom left NSTokenField.
I have tried following this section of the Apple developer documentation called Enable Tabbing Between Text Fields and dragging nextKeyView in Interface Builder between the fields in the order that I want. This seems to have absolutely zero effect on the tab order, and from what I can tell, Cocoa appears to still use its default detecting method to choose a tab order.
Any ideas? My target is 10.6+.
Make sure that you also set the initialFirstResponder outlet of the window to the first field (the table view in this case).
Sounds like you're going to have to do it programmatically:
Register for controlTextDidEndEditing notifications, identify the field by tag, and then call makeFirstResponder:fieldOfYourChoice on the window. And/or use an IBAction on the field, identifying it by sender, and call makeFirstResponder.