I have a view-based NSTableView for which some cells have enough content that it doesn't fit. I would like to be able to have the cell automatically expand when a user hovers their cursor over the cell.
In searching for this, it seems that this is the default behavior for a cell-based NSTableView. There are even methods like shouldShowCellExpansionForTableColumn, which the doc says is for cell-based table views only. Somewhere else in the doc implies that this expansion behavior is even on by default for cell-based table views?
- (BOOL)tableView:(NSTableView *)tableView shouldShowCellExpansionForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
I get the impression that I'm missing something obvious.
Goal:
Be able to put multiple rows of NSTextField objects in a view-based cell (more than there is pace to handle)
If the content overflows, put a visual indicator into the cell
When the user does a tool-tip style hover on the cell, expand the view to show all the content
You seem to be on the right track as this should work for cell based NSTableViews. You need to put tableView:shouldShowCellExpansionForTableColumn:row: in the tableView's delegate. You could reply YES for the column of interest.
With a view based table where you use NSTextFields these scroll, truncate or wrap but there is not an expand on hover option. It is possible to set the tooltip text to be the same as the content which might be a reasonable solution.
Did you try to change the row height (tableView:heightOfRow:) triggered by some mouse action? You might have to reload the tableview.
Related
I want to make a custom text selection in my table view.
I found this awesome answer on how to set the colors, fonts, etc. of the cells.
However, there is one issue.
It does not work for group rows. I see that the method gets invoked, but I think the style gets overwritten somewhere in either the NSTableCellView, or in the NSTableView class.
How can I fix this?
EDIT
It's a view based NSTableView
I've seen people doing this differently, I would prefer that when you select an item in UITableView (say in screen A), the item is highlighted(selected), and another screen B is pushed to the navigation stack, then when you go back from screen B to screen A, the previously selected item will be unselected with animation, so what you do is to put:
[self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];
inside:
- (void)viewWillAppear:(BOOL)animated;
and this is what Apple's sample code does. But I've seen a lot of people deselecting the row just after it is selected, inside:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
I know it may be just a personal preference, but I wonder is there any official clarification on this? Deselecting in viewWillAppear: lets users know his/her previously selected item, which is a bonus, but for some custom cell, the selected background/view may not be just solid color, and they may have a UIView added to the cell to represent the selected state, which makes the app inconsistent if some cells are deselected with animation and some are straight away after selected without animation.
Does anyone have any idea?
It's something that's up to you, if you are customising your applications UI extensively then you might not want to use this highlight at all. Maybe you have a complex cell and instead of using the cells selection trigger to drill down into a detail view or other, maybe you'll have a UIButton inside you cell.
It seems to me that UIKit wants to highlight the cell and retain it's highlight until you pop the detail view controller, at this point, presumably in viewWillAppear:, the currently selected cell of the UITableView is deselected, this allows you to have a very subtle and brief indication of which cell was selected to access where you've just come from.
Doesn't sound too interesting said like that however imagine if you exit the app and return some hours later, it's nice to have this small and as I said very subtle animation.
In the applications I've done in the past I've tended to not use this so much, or select but deselect immediately, so the user doesn't see a deselection animation upon returning or going "back" to the list. But that said all my cells in the applications I'm referring to have been very heavily customised.
I am wanting to change the text background color on a tableview's cell when it is hovered upon, similar to how AddressBook "highlights" the label of a contact's element when you mouseover the label names. However I cannot figure out how to accomplish...
detecting a mouseover on a particular NSCell and...
After detecting the cell his hovered upon, highlighting the text in that cell (not highlighting the entire row as if the user selected that row)
As NSCell is not a subclass of NSView this seems to be a very difficult task.
Any example of this or explanation on how this might be done would be greatly appreciated.
Thanks!
I actually got it working using another method. I got it from the example posted here... http://www.cocoadev.com/index.pl?NSTableViewRollover
https://web.archive.org/web/20111013060111/http://cocoadev.com/index.pl?NSTableViewRollover
Instead of using NSCell's tracking mechanism, I am tracking mouseEntered/mouseExited and mouseMoved within my subclassed NSTableView.
When the tableview awakeFromNib method is called, I create a trackingRect from the visible portion of the tableview
I have a BOOL ivar that is set to YES when the mouse is within the tracking area(mouseEntered) and NO when it is not (mouseExited)
Within the mouseMoved method, I determine the current row the mouse cursor is on and set it to an NSInteger ivar and then call the tableview's setNeedsDisplayInRect: passing the rect of the row that the mouse is on.
I also override resetCursorRects to remove the old tracking rect and add a new one...this method is called when the tableview is scrolled upon so that it's tracking the latest visible rect.
Finally in my tableview's delegate, I determine the selected row (by retrieving the row index from the NSInteger ivar of the table view and change the cell's text color (or anything you want) if the currently drawn cell matches the row the mouse cursor is on. All this is done in the delegate method: tableView:(NSTableView *)aTableView willDisplayCell:(id)aCell forTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex
I hope this helps others, as this was a bit tricky. It is also probably important to make sure that tableview is the firstResponder when the view loads, just makes things a bit more streamlined and cleaner.
Btw, is there a way to make a specific control in a view always be the firstResponder with nothing else possible as being the firstResponder? Even a method such as the iPhones... viewWillAppear method will help as I could set the first responder each time the view is visible...but i'm not aware of such a method on the Mac.
Overall, it's not a simple task as you noticed.
To track the mouse in an NSCell, subclass NSCell and override
-[NSCell startTrackingAt:inView:]
and
-[NSCell stopTracking:at:inView:mouseIsUp:]
Once you've detected the mouse is tracking inside a cell, you can find out which cell you are in the table with [tableView rowAtPoint:point] and [tableView columnAtPoint:point], and then find your frame with [tableView frameOfCellAtColumn:column row:row]
Then, you can change the way your cell is drawn by changing some property of the cell or changing the way it's drawn directly by overriding drawInteriorWithFrame:inView:.
Here's documentation on subclassing NSCell:
http://developer.apple.com/mac/library/documentation/cocoa/conceptual/ControlCell/Tasks/SubclassingNSCell.html
I achieved something similar by making use of addGlobalMonitorForEventsMatchingMask: handler: of NSEvent within my NSTableView subclass for the NSMouseMovedMask. using this along with columnAtPoint and rowAtPoint of NSTableView I was able to figure out if the position of the mouse was within a given cell.
Using this information I was able to bring up a PopOver when the mouse was over a particular cell.
I'm not asking how to do this, it's more in line of "What would you call this?".
I have an NSTableView with several custom cells. I want the table to scroll row by row, meaning that when I move the scrollbar up I want the top row to disappear and when I move it down I want the bottom row also to disappear - I don't want to see half my cell.
How do you call this type of behavior? And can you share some pointers if you've implemented it in a NSTableView?
I'm not exactly sure what this would be called (maybe something like "constrained scrolling"?), but you can do it using NSView's -adjustScroll: method.
The general approach is that you need to make a subclass of NSTableView (if you don't already have one), and override this method to return a NSRect that has its origin.y value constrained to a multiple of your row height.
You probably also want to use NSScrollView's -setVerticalLineScroll: to set the proper amount to scroll when the user clicks the scroll arrows in the vertical scroll bar. You can get the scrollView by calling -enclosingScrollView on your tableView.
I'm using a tableview to display a list of rows and when selected, I want additional controls to appear right below the cell, probably in another view which I will control.
So far, I've managed to get a reference to the selected cell by running through the visiblecells array in the tableview but the frame property always returns a y-coordinate of 0 no matter what scroll position the table is in.
How do I get the position of the cell relative to the window?
I think the best way to deal with table views is in their own terms. That is, if you want to position something new inside the table, put it in a cell. It sounds like you want to subclass UITableViewCell to make your controls, and go through the whole tableView beginUpdates - insertCells - endUpdates process to animate their appearance.