Context:
I have an NSOutlineView that acts like a source list, but does not use the actual source list highlighting style. (Imagine the sidebar in the Finder.)
This outlineView has only two levels: 1) "groups" and 2) "subitems". There is no additional nesting --- again, just like the source list in the Finder.
What I Want:
The top-level "group" rows in my OutlineView are NSTableCellViews with a single NSTextField. I would like my users to be able to edit the text in this textField (to rename the group) WITHOUT allowing them to select the entire group row in the OutlineView.
So far, I've not found a way to do this. If I prevent selection of group rows in my delegate for the OutlineView, it is not possible to edit the textfield. When I allow selection of the group rows, then I can get the textfield to edit just like any other.
Short of subclassing things and handling mouse events myself, is there a simple way to do this? Must a row in an NSTableView always be selected before textFields in that row can be edited?
I think it will work to use a custom subclass of NSOutlineView in which you override -validateProposedFirstResponder:forEvent: to return true if the proposed first responder is in a group row. Return whatever super returns for any other proposed first responder.
You can determine which row the proposed first responder is in by calling -rowForView:.
See this blog post from the Apple engineer who wrote the view-based table view stuff.
Related
I have a UITableView with gets populated from a backing array every time cellForRowAtIndexPath is called. The user can either go Back (via the nav bar) or they must submit the tableview's dataset to a server. Our GUI team wants the interface designed with a 'Done' button as the last cell in the table row in order to submit the dataset. Right now, numberOfRowsInSection is returning [myArray count] and I could conceivably alter the backing array with a "ghost" record for the done button, or simply return [myArray count] + 1 and catch the mis-matched array count in cellForRowAtIndexPath. Both ways, however, seem like trouble down the road. What's the best way to implement this?
Either put the button in the footer for the tableview, or mess with the row count. I've used both methods, just depends how much that last cell needs to look like the rest of the rows (or not look like them, in the case of using the footer)
I have a NSTableView with two columns, one is NSButtonCell and the other is a NSTextFieldCell. The text in NSTextFieldCell cannot be edited but the user can select a part of the text and make it bold. The current implementation is to allow them to do a double click and select a part of the text. The problem is, once the user is done bolding, the highlight color at selected row still persists.
The NSTableView usually has variable number of rows each time. I cannot do SelectRow as false as I need to be able to select the row. I also need to support 10.5.8 so I cannot set - NSTableViewSelectionHighlightStyle as None.
My application is a Cocoa application, which needs to run on 10.5.8, 10.6 and 10.7.
You can try setting the selected row as false. NSTableView has a method deselectRow. After bolding is done, you can deselect the row.
I am trying a simple application where I have a mutable array of mutable dictionaries, such as -
NSMutableDictionary *sample6 = [[NSMutableDictionary alloc] initWithObjectsAndKeys:#"title6",#"title",[NSNumber numberWithBool:NO],#"state", nil];
In IB I created a table view with NSButtonCell (check box).
I was able to show checkboxes state (checked or unchecked), using following table column bindings:
Value - ArrayController.arrangedObjects.state
In this case it shows an array of checkboxes with title - "Check" as shown in below screen-shot:
Now my aim is to show checkboxes title using bindings, such that it
gets value from same mutable dictionary from which it is getting its
state.
I tried following binding for button cell but it did not work:
title -> ArrayController.selection.title
I also tried this binding for button cell :
title -> ArrayController.arrangedObjects.title
but it didn't work, it appeared like this after using above binding:
Can any one suggest me which controller key to use and if this is not the correct way to show titles then what is the correct way to do so?
Unfortunately you'll need to write a little code if you want to do it this way. When binding table column values to an array, the table column is handling taking the prototype data cell, setting its values, and "stamping" it in place for each row. The button cell's bindings aren't exposed "through" the table column, so a simple binding won't do it for you.
To Answer Your Question
So. Since only the value binding is exposed, the title must be set manually if you really want the checkbox's title to reflect the value (ie, you really want the checkbox to handle both the check state and displaying the title). To do this, you have to mix bindings with < NSTableDelegateProtocol > . Use the -tableView:willDisplayCell:forTableColumn:row: method to set the cell's -title property to that of the proper object in your array controller's -arrangedObjects array each time you're asked. Mixing bindings and data source / delegate methods is actually quite common for more than the most basic applications, so don't worry that you're doing something dirty. Note: you won't be able to support editing the title by doing this since it's a checkbox.
An Alternative Design
Personally, I'd avoid all that and just add a separate table column for the title. Bind the new column's value to the array controller's arrangedObjects.title and turn off the checkbox button cell's title so only the checkbox itself is displayed. That simplifies the whole thing greatly and allows editing the title.
I just noticed a problem when my user-interface is in a certain state. I have a table view with two columns both of which the user can enter data that is to be used later. There's also a button which acts upon the contents of the table view.
The problem is if the user has entered new data in the column but has not yet exited the field by using the tab key or return key (i.e. the cursor is still in the field and in editing mode) and the button is pressed the old value is used not the current value sitting in the field.
What is the best way to handle this this? I want to use whatever the user has entered thus far.
Basically, The button code needs to tell the text field to finish completion or exit the editing mode. But I can't seem to find a method that will do that.
Use bindings. In Interface Builder, select the table column and in the Inspector go to Table Column Bindings and set the Value content binding appropriately and ensure the "Continuously Updates Values" option is checked. Then changes to the table cell content will propagate immediately.
Found the answer, At least for me.
Find out if a row is selected and if so deselect it. This causes the current entry to be completed.
- (void) completeTableEntry
{
// If a column is selected ensure it is completed
NSInteger sr = [keyValueTable selectedRow];
if (sr != -1) {
[keyValueTable deselectRow:sr];
}
}
How about:
[theTargetWindowWhateverThatIs endEditingFor:nil];
theTargetWindowWhateverThatIs may be, for example, self.window if you are inside a NSWindowController.
I'm trying to set up a UISearchBarDelegate
My first attempt was to clear the search results when searchBarShouldEndEditing: was called, but I discovered that this gets called when scrolling through the search results, which is not a time to be getting rid of the array of them.
My next attempt is searchBarCancelButtonClicked: - but this doesn't get called if the search bar is empty and they tap the space below (where a greyed out view of the table view is showing).
So how do you know when to switch from returning search results cells to returning regular table view cells?
Thanks for any help with this.
You can check which table view is requesting the cells. searchDisplayController.resultsTableView is what requests your search results cells. Just check for this in cellForRowAtIndexPath