How do I disable or remove the "replace" checkbox of NSTextFinder? - cocoa

My app displays a logfile in an NSTextView. I want the user to be able to search the output using the find bar, but not be able to replace any text. The NSTextView is set to be not editable, but when I press cmd-F, the find bar shows a "replace" checkbox:
I can prevent the user from being able to actually replace any text by implementing the NSTextViewDelegate protocol methods textView:shouldChangeTextInRange:replacementString: and
textView:shouldChangeTextInRanges:replacementStrings: but this does not remove or disable the checkbox. How can I do this?

NSTextFinder won’t present the Replace box if its findBarContainer’s editable property is NO (false).
You can set the property in code (the API is in the rarely-used superclass, NSText) or uncheck the box in Interface Builder.

Related

Editing text in field editor disables ⌘S when menu item is customized

When I bind "File > Save ⌘S" to a custom IBAction it works fine, except when I use the window's field editor to make something editable programmatically. (NSTableHeaderCells, specifically.)
When the cursor is in any NSTextField, ⌘S is still activated. That's what I want.
When the cursor is in the field editor (NSText based), ⌘S is deactivated. This only happens when I change the connection in MainMenu.nib to "First Responder > myCustomSaveMethod:".
Any ideas how to enable ⌘S-saving in the field editor in this case?
The reason this happened is that the "First Responder" is anything above the current view in the responder chain. The manually invoked field editor is inserted into the responder chain below NSWindowController. myCustomSaveMethod: is implemented in a sub-view controller which is not part of that responder chain, so the method definition isn't available to the field editor.
Moving myCustomSaveMethod: to a responder in the chain that both the table view and the field editor share (e.g. the NSWindowController) works like a charm.
¯\_(ツ)_/¯

Trying to see the delegate of an NSTextView of an NSCell

I am having a devil of a time trying to figure out how to get the address of the Text Field Editor (NSTextView) of an NSCell—NSFormCell and NSTextFieldCell in particular? NSCell does not have a property to access it. I did figure out the editor is not allocated until one is actually editing the field.
I want to set the delegate so I can capture keystrokes for auto-completion.
By default, there's a single field editor for each window. Even if a control or cell uses a custom field editor, it's still vended by the window. You would call -[NSWindow fieldEditor:forObject:] to obtain the field editor for a given control.
However, the delegate of the field editor is always set to the control on whose behalf it is working. Setting the delegate to something else is likely to break things. So, you would typically use a custom subclass of the control and implement your delegate methods there.
Finally, controlling completions is normally done using -textView:completions:forPartialWordRange:indexOfSelectedItem: in the text view delegate, not by capturing keystrokes.

Remove Focus from UITextField

I'm trying to remove focus from a UITextField and even though I resign it from being first responder, I'm still not able to have the cursor not focus on the text field.
I don't have any other input on the view to move the focus to and I don't want to create a dummy one either. What is a good workaround for this?
As per the documentation.
To dismiss the keyboard, send the resignFirstResponder message to the text field that is currently the first responder. Doing so causes the text field object to end the current editing session (with the delegate object’s consent) and hide the keyboard.
If you call resignFirstResponder on your textfield then it will end the editing session and the cursor wont be focussing on that textfield.
So please verify one more time whether resignFirstResponder is getting called on that textfield which you want to remove the focus.
Please try to set your current class as delegate of your UITextField. I think you forget to set the delegate that's why it's not working as you are expecting.

Specify editing NSTextField inside NSPopover on appearance

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.

NSTextFinder action on NSTextView

I'm trying to capture all the NSTextFinderClient calls on my custom NSTextView subclass.
The show action is called on my -(void)performTextFinderAction:(id)sender override, but for find next, find previous, etc. it's not called.
Any ideas?
Thanks!
Edit:
If you create a new project and drag an NSTextView from interface builder, command-g and command-shift-g (find next and find previous) don't work when the find bar is first responder.
Why is this?
I need a custom subclass of NSTextView to respond to the find bar for every event.
I searched in the Apple's TextEdit source code because with TextEdit, the standard search bar within the Text View works fine for command-G (and other shortcuts) even the search field is the first responder.
I found the solution.
Go to your nib for the main menu, and select the "Find" (and related) menu items. They should be bound to the default action called "performFindPanelAction:." Now unbind them and bind to "performTextFinderAction:" of the First Responder instead.
You may not find that action in the First Responder's action list. So you need to add it by yourself in the First Responder's attributes inspector pane.
This was meant by the document below saying
Before OS X v10.7, the default action for these menu items was performFindPanelAction:. Whenever possible which you should update your implementation to use this new action.
https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSResponder_Class/#//apple_ref/occ/instm/NSResponder/performTextFinderAction:
The find bar communicates privately with the client's NSTextFinder instead of calling NSResponder's -performTextFinderAction:. This is necessary to allow find to work when something besides the client has key focus.
What are you trying to accomplish?

Resources