How to mimic the item highlight behavior of NSTableView in NSCollectionView? - macos

I have NSCollectionView with custom items which contain NSTextField and NSImageView.
I realized highlight behavior of collection view items manually (ie. redefined the setSelected: method in my NSCollectionViewItem descendant class).
I successfully change the background color of selected items, but I miss one small but important thing: the text color of the selected item doesn't change.
I know that the NSTableView item highlighting changes the text color along with the background color, but I cannot mimic it since I don't know the algorithm of color's change.
The text color of my NSCollectionViewItems can be different. When I highlight the item in NSTableView, the gray text becomes lightgray, black becomes white and so on.
Does anybody know how they do that? Maybe there's a ready solution in the Cocoa API that I missed? Please help.

Related

How to display elements inside NSCollectionView with various shapes

I am a rookie Cocoa guy. I need to design and implement a view which will show collection of labels on Mac OS using Xamarin. These labels will have a text and color associated with them. When shown inside the view, label should expand till it covers whole text and it will be shown with background and foreground colors.
I have attached the picture of this user control on Windows, you can see that labels inside the StackPanel are expanding till they cover the whole text. Hope this gives better idea about my ask.
The $64,000 question is "are these labels controls?" In other words, do you expect the user to click on these to do something, or are they just for display?
If your answer is "just for display", the solution is super simple: Use an NSTextField and programmatically add attributed text (NSAttributedString) to it. Attributed text attaches display properties to runs of text within the field; properties like "background color".
If you want these to be buttons that you can click on, then things get a lot more complicated.
Since you apparently want the button layout to "flow", you might look into imbedding buttons (well, button cells) into an NSTextField using attachments. This is normally how non-text content (say, an image) can be inserted, but with some fiddling it can actually be anything a control cell can draw. See How to insert a NSButton into a NSTextView? (inline).
Warning: this is not a "rookie" topic and will involve control cells and custom event handling.
If I were doing this, I'd probably just create NSButton objects for each label (choosing an appropriate style/look like NSRecessedBezelStyle), create a custom subclass of NSView to contain them, and then override the layout method to position all of the buttons the way I want.
To be thorough, I'd also override the intrinsic size methods so the whole thing could participate in auto-layout, based on the number and size of buttons it contained.

NSOutlineView - Disclosure Triangle Interferes with Highlight Rectangle

I have an NSOutlineView with the highlight mode set to source list and the menu property set to a non-empty menu (I figured this last consdition is necessary to have the outline drawn).
When I right-click on a row representing an item that has children (i.e., is expandable), The blue outline around the cell has a slightly different color right above and below the disclosure triangle:
(This happens for every node, at every level of the hierarchy)
Additional information: My outline view is view based, does not use bindings (view controller is the delegate and data source).
Me cells are custom, designed on the storyboard, nothing fancy (icon image view and text field).
What can be causing this?
EDIT: The issue only appears with the round-cornerered highlight rectangle of the "Source List" highlight mode. With the straight-cornered rectangle of the "Regular" highlight mode, the stroke color is even all along.
When using the Source List style, your outline view has an NSVisualEffect view behind it, which causes the list to be composited differently. What you're seeing seems to be a bug with the vibrancy appearance. You could perhaps try to work around it by reducing the frame of the outline cell by overriding frameOfOutlineCell.

How to remove NSTableView's border and change cell selection color as same as Finder's?

I'm making an Cocoa app for Yosemite.
I added a view based NSTableView in Interface builder, but the border 2 pixel width and thicker than Yosemite's Finder's.
And the cell selection color is blue, while Yosemite's Finder's is gray.
And this is how Yosemite's Finder's table view looks like.
I checked the settings in Interface Builder.
The super scroll view of NSTableView's frame setting is (0,0,149,257):
While the Clip View's frame setting is (1, 1, 147, 255) and can not be changed.
And how to make a same NSTableView as Yosemite's Finder's?
Thanks a ton!
The Finder sidebar isn't a table-view it's a Source List NSOutlineView:
The border is applied around the enclosing scroll view:
Note also that a standard NSOutlineView lets you adjust the highlight style from within Interface Buider:
In my experience selected rows are still painted blue, even when the "Source List" highlight style is selected. To avoid that, I needed to prevent the table or outline view from becoming the first responder by subclassing it and adding
- (BOOL)becomeFirstResponder {
return NO;
}
Edit:
Turns out becomeFirstResponder is actually important if you want to support keyboard navigation. I have found a better solution that does not override becomeFirstResponder.
First, create a custom NSTableRowView subclass with an (overridden) empty setEmphasized: method:
- (void)setEmphasized:(BOOL)emphasized {
// This avoids a blue background when selected in a source list that has first responder status.
}
You can then provide an instance of your custom NSTableRowView class by implementing
- (NSTableRowView *)tableView:(NSTableView *)tableView rowViewForRow:(NSInteger)row
in your NSTableViewDelegate.
To whoever wants to remove the NSTableView border...
My requirement was to remove the border colour of the NSTableView so that, it should look like a white box. Tried all properties and forums but couldn't find a way to do that. Finally I came up with a dirty hack in the Storyboard which could fix the problem. If someone have a better option, please let us know.
Embed the NSTableView in a CustomBox. Set the Box BorderType as 'None'
Then set the constraints (Left, Top, Right and Bottom) of NSTableView to the containing Box. Set the values to -2. so that the NSTableView border will be outside of the Box
Now in Storyboard, select the 'clipView(NSClipView)' of the NSTableView. clipView is the superView of the NSTableView
Go to the Size Inspector and uncheck the 'Automatically Adjust' property of the "Content Insets"
Set the values to Left=2, Top=2, Bottom=-2 and Right=-2
Thats it.

NSWindow and text smoothing in NSTableView cell view

I'm writing an OS X app and have a problem with font smoothing in separate window.
I have a text field where you put text and suggestion window which pops up with a list of suggestions according to what you wrote. I'm using View-cell based NSTableView to display those suggestions and SFBPopoverWindowController to display it as a "popup" window (tried other classes with the same effect). When rows are first drawn they look fine but after I select them (keyboard or mouse) the font changes it's weight. It's only visual - like you would change smoothing method on the font, not it's bold setting.
"Music note" is the selected cell here
What's even more strange is that after I hide and show the window 3 times everything works fine from that point on.
Again - "Music note" is the selected cell.
The selection is done by overwriting NSTableRowView class and its drawSelectionInRect: method but I tried with drawing everything inside custom NSTableCellView class and it didn't help. The text is standard NSTextField - nothing's changed there.
The SFBPopoverWindow (and it's controller) are created once and reused with styleMask NSBorderlessWindowMask, backing NSBackingStoreBuffered, defer set to YES. The only change in SFBPopoverWindowController I made was to turn off window becoming key window but it doesn't change anything.
It might be related to the way a table view draws it's selected cells (setSelectionHightLightStyle:). Try to set the style to None/ NSTableViewSelectionHighlightStyleNone in your code or IB / Storyboard-file and draw the selection yourself (in a NSTableRowView subclass).
Background: When you use NSTableViewSelectionHighlightStyleRegular or NSTableViewSelectionHighlightStyleSourceList the table view assumes that you use the standard selection behaviour and appearance and does some magic to support that.
==========
UPDATE
==========
My previous answer is still valid but since it only describes the problem and hints at a workaround, I wanted to add a real solution. If you want to use NSTableViewSelectionHighlightStyleRegular for your table view (with custom font and colors), you need a way to 'disable' the system magic that comes into place once your row is highlighted. One proposed solution is to decline the first responder status. It has a lot of drawbacks and isn't a good solution at all.
So, let's have a closer look at the system 'magic' that kicks in as soon as the row will be highlighted: NSTableRowView has a property interiorBackgroundStyle that is – according to the documentation – 'an indication of how the subviews should draw'. Furthermore 'This value is dynamically computed based on the set of properties set for the NSTableRowView. Subclassers can override this value when they draw differently based on the currently displayed properties. This method can also be called to determine what color a subview should use, or alternatively, NSControls can have the -backgroundStyle set on their cell to this value.'
I assume that this style will be handed down the subview hierarchy and causes your text fields to look odd. The system assumes that a highlighted cell has a dark background and changes the interiorBackgroundStyle to dark. Other controls try to adapt accordingly.
I think there are two solutions to this problem:
1) Override interiorBackgroundStyle in your NSTableRowView subclass and return the style that fits your interface (in my case it's .light because my highlight color is a very bright blue). This worked for me.
2) If changing the whole style is a bit too much because you only want certain elements to not change their style, you may only need to adjust these subclasses. I haven't tried this yet.

Table view cell, custom editor and editing frame

I am using a custom editor when editing the contents of a cell inside a Table view. From the docs I see that the custom editor has to be an NSTextView. So I put the text view in the document view, then I referenced it from the cell subclass through an IBOutlet in order to assign it as custom editor.
When doing all this, I can set the editor not to draw its background, but a thick white border is shown when the user edits that cell, and there is no way to remove it.
So I create the NSTextView programmatically, assigned it as the custom editor, and no white border is shown, but I can't change the background now, set it to clearColor, set the font, fontColor etc. I can't do anything with it. It is just a square with dark background and white text.
Is there something I am not doing? This is a bad approach?
Thank you.
The border is drawn by drawRect:, but I still don't know how to fix it by overriding drawRect:...
You may have a look at this link: http://www.cocoabuilder.com/archive/cocoa/129091-solved-re-disabling-nstableview-big-black-editing-box.html#129259

Resources