My application has a NSTableView configured as a SourceList.
Under the NSTableView are two NSButton two add/remove items in the table.
The table and the buttons are embedded in a NSVisualEffectView (.behindWindow mode).
The result is great and I can see the background through the table and the buttons, BUT, when the app is in background (I give the focus to another app), the tableview and the buttons become black, and the view is not redrawn, as shown in the picture below (taken with an iPhone, because a screenshot does not show the bug!):
And here is the IB structure of the views:
The container view (CustomView) is layer-backed.
Any lead to solve this problem? Thanks in advance !
The problem was that I was trying to have a NSOutlineView translucent (Behind-window blending), but under a TabView.
Apple UI guidelines (here) state the following:
Use an opaque background when a window contains more than one sidebar, and when using a sidebar in a panel or preferences window. All other times, use a translucent background.
Because of the TabView, I was clearly against this rule which had technical side effects (which led to this post :-)).
--> making the NSOutlineView opaque (not as a SourceList) solved the problem.
Are any of your views opaque and implement drawRect:?
I've seen issues like this when a view implements drawRect: but doesn't completely fill the passed-in rect (or all of the rects returned from getRectsBeingDrawn:count:).
Related
I've got a Mac app involving an NSOutlineView. The view controller containing the outline view implements outlineViewSelectionIsChanging: to set selection state in a custom way on the cells in the outline view (it's view-based). But selectionIsChanging is called on mouse up, not mouse down. I've got other view controllers with other outline views in the app that get selectionIsChanging properly on mouse down, but I can't find a difference. Is this a property on NSOutlineView / NSTableView? Or is there another probable cause of this?
Turns out that if drag-and-drop is implemented on the outline view, it only posts selection messages on mouse up.
Several places in OS X (in this example, the Users & Groups pane in System Preferences) have circular image views that allow the user to either drag in an image, like in an editable NSImageView but also allow them to click to show a popover that allows various other choices of image sources.
I have checked the ImageKit framework, but the only thing I found similar is the image taking sheet.
How can I make use of this feature in my own Cocoa applications? I'd imagine it is implemented in some standard frameworkâbut any pointers on implementing something like this would be quite appreciated.
You will have to go down the custom control root as this is not available as a stand alone control.
However you have all the prerequisites.
The circular image view
There a several ways to implement this. You could try using a standard Cocoa button and customise as needed. Although it might just be easier to build from scratch by subclassing NSView. This was you can avoid all the NSCell stuff. I would do the latter.
The popover
Roll your own master-details type view controller to be displayed as the popover's content. In the left have a NSTableView (the master), the right have a NSCollectionView (the details). Below the collection view add some buttons.
I'm trying to add a "second row" after my NSToolbar in my app, that remains part of the title bar. As an example, Mail has a thin gray divider line below the NSToolbar with some extras items below that. Very specifically, when the window is put into fullscreen mode, that second "row" stays attached to the title bar as it slides down under the system menu bar. Xcode has a similar story.
I tried setting my NSWindow to textured and placing my second row controls directly in the content view of the window. While this mostly looks correct in windowed mode, those controls of course won't appear attached to the toolbar when it slides down in fullscreen mode. So how can I achieve the same behavior that Mail and Xcode do? I've looked at a lot of toolbar customization code but none of them really cover this specific case.
fullScreenAccessoryView is deprecated in macOS 10.10
In order to do this in recent versions of macOS, use the addTitlebarAccessoryViewController method on your NSWindow and pass in a subclass of NSTitlebarAccessoryViewController.
For example:
NSTitlebarAccessoryViewController *accessoryViewController = [[NSStoryboard storyboardWithName:#"Main" bundle:nil] instantiateControllerWithIdentifier:#"AccessoryViewController"];
[self.mainWindowController.window addTitlebarAccessoryViewController:accessoryViewController];
What I needed to do was call [NSToolbar setFullScreenAccessoryView:] on the view below my toolbar. This results in the behavior I was aiming for. See the NSToolbar documentation for this method.
First one is normal toolbar. For second toolbar you can create a separate view of your desired height and add it in the main landing-window.
I'm having a problem since Lion introduced elastic scrolling (pictured below). When you scroll my table view (cell-based, with alternating row colors) beyond its bounds, the background doesn't draw. I've tried doing my own drawing in -[drawBackgroundInClipRect:], but it seems like you can't exceed the bounds of the table view. How can I extend the background into elastic scrolling territory?
In Answer to Your Question
A view drawing outside its bounds is generally a no-no. When using alternating background colors, the NSTableView draws its background directly. But in a view-based table view, NSTableRowView is used and if it has its own background color, this is poses even more challenge.
The Bad News
The assemblage of NSScrollView (and its various parts), NSTableView, and NSTableHeaderView is complicated on its own. Once you throw view-based functionality into the mix (where each row has a view and each cell has their own view, and each are reused, animated around, etc.), overriding this behavior "is no way to go through life, son!" ;-)
The Good News
The issue of alternating background colors not extending in an elastically-stretched scrolled table view has been resolved (at least on 10.10, that I can tell), so this is no longer an issue unless you have row/cell views with custom backgrounds or just background colors.
A General Solution For Custom Document (Scrolled) Views
For all other scrolled views with ruled backgrounds you wish to extend for elastic scrolling, you'll need a custom NSScrollView subclass that expects a document view (your custom scrolled view) to conform to a protocol you define (like -(NSImage *)backgroundImageForClipViewBounds:). The scroll view would observe its content view (NSClipView) for bounds change notifications and flag itself for display. When the scroll view's -drawRect: is called, it would then ask the scrolled view for its -backgroundImageForClipViewBounds: (via your protocol) and draw it into itself, thereby making the scrolled view's "infinite background" its own.
I haven't tested this theory but I believe it would work. I hope this helps.
Is there any way to have 2 toolbars in one NSWindow. Something like Pages. With one large on at the top, and a smaller one below that.
NSWindow only supports one NSToolbar.
If you want to have a "second level" like Pages, you'll need to create your own non-NSToolbar-based solution.
Note that in Pages, the smaller "toolbar" isn't really a toolbar (as in NSToolbar), and is not editable. You should be able to recreate this with a simple custom view to draw the top and bottom lines, but let the window background through. Just position the view and set its autosizing as appropriate, then add your controls to the view.
Update: I believe NSBox can be configured to draw specific edges as of Leopard or Snow Leopard. Just a thought.