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:
Related
I have a view-based NSTableView containing a list of words. When the user double-clicks on a word, I would like to take an action. The words are not editable or selectable. How do I do this?
I have tried setting the target and action of the table view in IB, but it only calls the action method when the user clicks in the header of the table, not in one of the words.
I have tried setting the target and action of the NSTextField that the table cell view keeps in IB. This results in this error message being repeated in the console:
2018-01-02 14:14:32.080347-0800 WordExplorer[7089:21457459] Could not connect action, target class NSObject does not respond to -relatedWordClick:
However the target class does respond to the selector. (I connected it in IB directly, so clearly, it does!) It is also not a simple NSObject, so I'm guessing that something else is going wrong there.
I have tried manually calling -setTarget: and -setAction: on the NSTextField contained in the table cell view in my delegate's -tableView:viewForTableColumn:row: method. This has no effect, and the debugger shows that despite calling those methods, they do not set the text field's action or target method. (Though, given this is Xcode we're talking about, it's likely that's just a debugger display issue.) I get no errors in the console like when I make the connection in IB, but it also does not call the appropriate method.
Do I need to make custom view class and use that for the table cell view? Or is there a simpler way to get clicks (and preferably double-clicks) on words in my list?
Simply create an IBAction on the object you have as the NSTableView's target, and then set the NSTableView's doubleAction property to the selector for that IBAction, and you can handle double-click events easily.
I have an NSTextField in a view that is bound to a value in the view's view controller. When a button is pressed I wish to make the text field no longer editable so I use the following code:
- (IBAction)makeTextFieldNotEditable:(id)sender {
self.textField.editable = NO;
}
Everything is bound correctly and I can confirm that the above method gets called when I press the button but the text field is still editable. How can I fix this?
This was because by default when you bind the value of an NSTextField in Interface Builder it ticks the box Conditionally Sets Editable meaning that the value the text field is bound to sets the editable property of the text field.
Unticking this box made my original code work.
How to configure a view-based NSTableView to behave like so:
Rows are selectable
The user are unable to trigger edit mode by clicking a cell
Edit mode can be triggered by calling NSTableView-editColumn:row:withEvent:select: programmatically
The table view is dragged from the object library of Xcode interface builder, i.e., it uses an NSTableCellView (with an NSImageView and an NSTextField as its subviews) as the table view's cell view.
For view-based table views, -editColumn:row:withEvent:select: is relatively ineffective. It attempts to make the cell view the first responder for the window, but only certain views will accept first responder status. NSTableCellView does not, because it is not itself editable.
If you want to programmatically initiate editing in the text field within an NSTableCellView, you can do something like:
NSTableCellView* cellView = (NSTableCellView*)[tableView viewAtColumn:col row:row makeIfNecessary:YES];
if ([cellView.textField acceptsFirstResponder])
[cellView.window makeFirstResponder:cellView.textField];
To disable the user from starting editing through the UI, I think you will need to set the text field to not be editable. You would make it editable just before you initiate editing programmatically. For example, add a line cellView.textField.editable = YES; between the above two lines.
Then, you'll want to set it back to non-editable after editing ends. To do this, you can set the delegate of the text field to your controller object and implement -controlTextDidEndEditing:. Or, similarly, you can add an observer of the NSControlTextDidEndEditingNotification notification from the text field. Either way, when your code is called, you set the text field's editable property back to false. (If you don't otherwise have a reference to the text field in question, you can obtain it from the NSNotification's object property.)
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.
I have a Core Data project.
Basically I have an NSTableView where I add some entities (using the "add:" selector), double clicking on the TableView opens a new NSWindow where is possible to edit the entity using some NSTextFields.
Each text field is binded to an attribute of the entity.
Everything is working fine, except the fact that the entity's attributes are updated only when a textfield lose the focus.
If I write on the first text field and then I move to the second one my entry is saved, but if I write on the first text field and I close the window I lose my changes.
How can I update my core data entity as soon as I write something in the text field? Should I use textDidChange:?
--- UPDATE ---
Unfortunately [context save] doesn't work. If I understand correctly the entity is not modified until the NSTextField resign first responder.
The only working solution for now is something like:
(void)controlTextDidChange:(NSNotification *)aNotification
{
NSTextField *tf = [aNotification object];
[self.window makeFirstResponder:tf];
}
but this is quite inelegant, and in any case I also still need to re-set the cursor at the end of the NSTextField.
Setting NSContinuouslyUpdatesValueBindingOption will cause the model to update every time the text field changes, which sets the dirty flag properly and causes the document to save on quit.
I think you could use DidEndEditing or TextDidChange, another way of doing this is handeling in the window close event, but I would not recommend it.
If you don't have one already, you can set a delegate on the window and use -windowWillClose: or observe the NSWindowWillCloseNotification. You can then call [[notification object] makeFirstResponder:[window initialFirstResponder]] to set the window's first responder to its initial first responder as the window is closing. This will cause the control that is first responder (e.g. NSTextField) to resign the first responder status and the binding will save the changes.