This article covers several tips, features and techniques a developer can use to build a modern macOS app in Xamarin.Mac.
-->
On your Mac, do any of the following in an app: Hide or show the toolbar: Choose View Hide Toolbar or View Show Toolbar. While working in full screen for some apps, choose View Always Show Toolbar in Full Screen. Remove a button: Hold down the Command key while you drag the item out of the toolbar until you see or hear a “poof” effect. Jan 16, 2019 How to automatically hide or show the Dock on your Mac. On smaller laptop screens, every bit of screen space is valuable. If you don't want the Dock getting in the way of your productivity, you can keep it hidden until you want to access it, at which point, you can call it back up by hovering your cursor over the place where it normally resides.
Building Modern Looks with Modern Views
A modern look will include a modern Window and Toolbar appearance such as the example app shown below:
Enabling Full Sized Content Views
To achieve this looks in a Xamarin.Mac app, the developer will want to use a Full Size Content View, meaning the content extends under the Tool and Title Bar areas and will be automatically blurred by macOS.
To enable this feature in code, create a custom class for the
NSWindowController and make it look like the following:
This feature can also be enabled in Xcode's Interface Builder by selecting the Window and checking Full Sized Content View:
When using a Full Size Content View, the developer may need to offset the content beneath the title and tool bar areas so that specific content (such as labels) doesn't slide under them.
To complicate this issue, the Title and Tool Bar areas can have a dynamic height based on the action that the user is currently performing, the version of macOS the user has installed and/or the Mac hardware that the app is running on.
As a result, simply hard coding the offset when laying out the User Interface will not work. The developer will need to take a dynamic approach.
Apple has included the Key-Value Observable
ContentLayoutRect property of the NSWindow class to get the current Content Area in code. Native apps for mac os. The developer can use this value to manually position the required elements when the Content Area changes.
The better solution is to use Auto Layout and Size Classes to position the UI elements in either code or Interface Builder.
Code like the following example can be used to position UI elements using AutoLayout and Size Classes in the app's View Controller:
This code creates storage for a top constraint that will be applied to a Label (
ItemTitle ) to ensure that it doesn't slip under the Title and Tool Bar area:
By overriding the View Controller's
UpdateViewConstraints method, the developer can test to see if the needed constraint has already been built and create it if needed.
If a new constraint needs to be built, the
ContentLayoutGuide property of the Window the control that needs to be constrained is accessed and cast into a NSLayoutGuide :
The TopAnchor property of the
NSLayoutGuide is accessed and if it is available, it is used to build a new constraint with the desired offset amount and the new constraint is made active to apply it:
Enabling Streamlined Toolbars
A normal macOS Window includes a standard Title Bar at runs along to top edge of the Window. If the Window also includes a Tool Bar, it will be displayed under this Title Bar area:
When using a Streamlined Toolbar, the Title Area disappears and the Tool Bar moves up into the Title Bar's position, in-line with the Window Close, Minimize and Maximize buttons:
The Streamlined Toolbar is enabled by overriding the
ViewWillAppear method of the NSViewController and making it look like the following:
This effect is typically used for Shoebox Applications (one window apps) like Maps, Calendar, Notes and System Preferences.
Using Accessory View Controllers
Depending on the design of the app, the developer might also want to complement the Title Bar area with an Accessory View Controller that appears right below the Title/Tool Bar area to provide context sensitive controls to the user based on the activity they are currently engaged in:
The Accessory View controller will automatically be blurred and resized by the system without developer intervention.
To add an Accessory View Controller, do the following:
Edit the
NSWindowController and make it look like the following:
The key points of this code are where the View is set to the custom View that was defined in Interface Builder and exposed as an Outlet:
And the
LayoutAttribute that defines where the accessory will be displayed:
Because macOS is now fully localized, the
Left and Right NSLayoutAttribute properties have been deprecated and should be replaced with Leading and Trailing .
Using Tabbed Windows
Additionally, the macOS system might add Accessory View Controllers to the app's Window. For example, to create Tabbed Windows where several of the App's Windows are merged into one virtual Window:
Typically, the developer will need to take limited action use Tabbed Windows in their Xamarin.Mac apps, the system will handle them automatically as follows:
Bringing all of the pieces together, the
AppDelegate of an app that wanted to use system based Tabbed Windows could look like the following:
Where the
NewDocumentNumber property keeps track of the number of new documents created and the NewDocument method creates a new document and displays it.
The
NSWindowController could then look like:
Where the static
App property provides a shortcut to get to the AppDelegate . The SetDefaultDocumentTitle method sets a new documents title based on the number of new documents created.
The following code, tells macOS that the app prefers to use tabs and provides a string that allows the app's Windows to be grouped into Tabs:
And the following override method adds a plus button to the Tab Bar that will create a new document when clicked by the user:
Using Core Animation
Core Animation is a high powered graphics rendering engine that is built into macOS. Core Animation has been optimized to take advantage of the GPU (Graphics Processing Unit) available in modern macOS hardware as opposed to running the graphics operations on the CPU, which can slow down the machine.
The
CALayer , provided by Core Animation, can be used for tasks such as fast and fluid scrolling and animations. An app's User Interface should be composed of multiple subviews and layers to fully take advantage of Core Animation.
A
CALayer object provides several properties that allow the developer to control what is presented onscreen to the user such as:
To utilize Core Graphics in the app's UI, it must be using Layer Backed Views, which Apple suggests that the developer should always enable in the Window's Content View. This way, all child views will automatically inherit Layer Backing as well.
Additionally, Apple suggests using Layer Backed Views as opposed to adding a new
CALayer as a sublayer because the system will automatically handle several of the required settings (such as those required by a Retina Display).
Layer Backing can be enabled by setting the
WantsLayer of a NSView to true or inside of Xcode's Interface Builder under the View Effects Inspector by checking Core Animation Layer:
Access Apps Automatically On Toolbar Apps On Mac DownloadRedrawing Views with Layers
Another important step when using Layer Backed Views in a Xamarin.Mac app is setting the
LayerContentsRedrawPolicy of the NSView to OnSetNeedsDisplay in the NSViewController . For example:
If the developer doesn't set this property, the View will be redrawn whenever its frame origin changes, which is not desired for performance reasons. With this property set to
OnSetNeedsDisplay the developer will manually have to set NeedsDisplay to true to force the content to redraw, however.
When a View is marked as dirty, the system checks the
WantsUpdateLayer property of the View. If it returns true then the UpdateLayer method is called, else the DrawRect method of the View is called to update the View's contents.
![]()
Apple has the following suggestions for updating a Views contents when required:
To use
UpdateLayer , create a custom class for the NSView and make the code look like the following:
Using Modern Drag and Drop
To present a modern Drag and Drop experience for the user, the developer should adopt Drag Flocking in their app's Drag and Drop operations. Drag Flocking is where each individual file or item being dragged initially appears as an individual element that flocks (group together under the cursor with a count of the number of items) as the user continues the drag operation.
If the user terminates the Drag operation, the individual elements will Unflock and return to their original locations.
The following example code enables Drag Flocking on a custom View:
The flocking effect was achieved by sending each item being dragged to the
BeginDraggingSession method of the NSView as a separate element in an array.
When working with a
NSTableView or NSOutlineView , use the PastboardWriterForRow method of the NSTableViewDataSource class to start the Dragging operation:
This allows the developer to provide an individual
NSDraggingItem for every item in the table that is being dragged as opposed to the older method WriteRowsWith that write all of the rows as a single group to the pasteboard.
When working with
NSCollectionViews , again use the PasteboardWriterForItemAt method as opposed to the WriteItemsAt method when Dragging begins.
The developer should always avoid putting large files on the pasteboard. New to macOS Sierra, File Promises allow the developer to place references to given files on the pasteboard that will later be fulfilled when the user finishes the Drop operation using the new
NSFilePromiseProvider and NSFilePromiseReceiver classes.
Using Modern Event Tracking
For a User Interface element (such as a
NSButton ) that has been added to a Title or Tool Bar area, the user should be able to click the element and have it fire an event as normal (such as displaying a popup window). However, since the item is also in the Title or Tool Bar area, the user should be able to click and drag the element to move the window as well.
To accomplish this in code, create a custom class for the element (such as
NSButton ) and override the MouseDown event as follows:
This code uses the
TrackEventsMatching method of the NSWindow that the UI element is attached to intercept the LeftMouseUp and LeftMouseDragged events. For a LeftMouseUp event, the UI element responds as normal. For the LeftMouseDragged event, the event is passed to the NSWindow 's PerformWindowDrag method to move the window on screen.
Calling the
PerformWindowDrag method of the NSWindow class provides the following benefits:
Using Modern Container View Controls
macOS Sierra provides many modern improvements to the existing Container View Controls available in previous version of the OS.
Table View Enhancements
The developer should always use the new
NSView based version of Container View Controls such as NSTableView . For example:
This allows for custom Table Row Actions to be attached to given rows in the table (such as swiping right to delete the row). To enable this behavior, override the
RowActions method of the NSTableViewDelegate :
The static
NSTableViewRowAction.FromStyle is used to create a new Table Row Action of the following styles:
Scroll View Enhancements
When using a Scroll View (
NSScrollView ) directly, or as part of another control (such as NSTableView Time passages astrology software for mac. ), the contents of the Scroll View can slide under the Title and Tool Bar areas in a Xamarin.Mac app using a Modern Look and Views.
As a result, the first item in the Scroll View content area can be partially obscured by the Title and Tool Bar area.
To correct this issue, Apple has added two new properties to the
NSScrollView class:
By using the
ContentInsets the developer can adjust the start of the Scroll View to allow for the inclusion of accessories such as:
Auto Layout and Localization in Modern Apps
Apple has included several technologies in Xcode that allow the developer to easily create an internationalized macOS app. Xcode now allows the developer to separate user-facing text from the app's User Interface design in its Storyboard files and provides tools to maintain this separation if the UI changes.
For more information, please see Apple's Internationalization and Localization Guide.
Implementing Base Internationalization
By implementing Base Internationalization, the developer can provide a single Storyboard file to represent the app's UI and separate out all of the user-facing strings.
When the developer is creating the initial Storyboard file (or files) that define the app's User Interface, they will be built in the Base Internationalization (the language that the developer speaks).
Next, the developer can export localizations and the Base Internationalization strings (in the Storyboard UI design) that can be translated into multiple languages.
Later, these localizations can be imported and Xcode will generate the language-specific string files for the Storyboard.
Implementing Auto Layout to Support Localization
Because localized versions of string values can have vastly different sizes and/or reading direction, the developer should use Auto Layout to position and size the app's User Interface in a Storyboard file.
Apple suggest doing the following:
Localizing in Xcode's Interface Builder
Apple has provided several features in Xcode's Interface Builder that the developer can use when designing or editing an app's UI to support localization. The Text Direction section of the Attribute Inspector allows the developer to provide hints on how direction should be used and updated on a select Text-Based View (such as
NSTextField ):
There are three possible values for the Text Direction:
There are two possible values for the Layout:
Typically these should not be changed unless a specific alignment is required.
The Mirror property tells the system to flip specific control properties (such as the Cell Image Position). It has three possible values:
If the developer has specified Center, Justify or Full alignment on the content of a text-based View, these will never be flipped based on language selected.
Prior to macOS Sierra, controls created in code would not be mirrored automatically. The developer had to use code like the following to handle mirroring:
Where the
Alignment and ImagePosition are being set based on the UserInterfaceLayoutDirection of the control.
macOS Sierra adds several new convenience constructors (via the static
CreateButton method) that take several parameters (such as Title, Image and Action) and will automatically mirror correctly. For example:
Using System Appearances
Modern macOS apps can adopt a new Dark Interface Appearance that works well for image creation, editing or presentation apps:
This can be done by adding one line of code before the Window is presented. For example:
The static
GetAppearance method of the NSAppearance class is used to get a named appearance from the system (in this case NSAppearance.NameVibrantDark ).
Apple has the following suggestions for using System Appearances:
A macOS app that uses the System Appearances will automatically work correctly for users that have enabled Accessibility features from the System Preferences app. As a result, Apple suggests that the developer should always use System Appearances in their macOS apps.
Designing UIs with Storyboards
Storyboards allow the developer to not only design the individual elements that make up an app's User Interface, but to visualize and design the UI flow and the hierarchy of the given elements.
Controllers allow the developer to collect elements into a unit of composition and Segues abstract and remove the typical 'glue code' required to move throughout the View Hierarchy:
For more information, please see our Introduction to Storyboards documentation.
There are many instances where a given scene defined in a storyboard will require data from a previous scene in the View Hierarchy. Apple has the following suggestions for passing information between scenes:
The View Controller that is acting as the source of the Segue, can override the
PrepareForSegue method and do any initialization required (such as passing data) before the Segue is executed to display the target View Controller. For example:
For more information, please see our Segues documentation.
Propagating Actions
Based on the design of the macOS app, there might be times when the best handler for an Action on a UI control might be in elsewhere in the UI Hierarchy. This is typically true of Menus and Menu Items that live in their own scene, separate from the rest of the app's UI.
To handle this situation, the developer can create a Custom Action and pass the Action up the responder chain. For more information please see our Working with Custom Window Actions documentation.
Modern Mac Features
Apple has included several user-facing features in macOS Sierra that allow the developer to make the most of the Mac platform, such as:
Summary
This article has covered several tips, features and techniques a developer can use to build a modern macOS app in Xamarin.Mac.
Related LinksToolbars
A toolbar provides convenient access to frequently used commands and features, and resides in the frame at the top of a window, either below or integrated with the title bar. In Pages, for example, the toolbar includes the commands people use most often as they view, create, and collaborate on documents.
For developer guidance, see NSToolbar.
Toolbar Items
The elements within a toolbar are called toolbar items and consist of either image buttons or specific system controls that are optimized for use in the toolbar.
System controls
Provide toolbar items for the things people do most often. The purpose of the toolbar is to provide shortcuts to common tasks within the app or current window.
Include image buttons or system controls, but not both. Toolbars look best and are easiest to understand when they contain elements of the same type.
Use only toolbar-specific system control styles. Only the following system control styles should be used in the toolbar. Because they’re designed to closely integrate with the toolbar’s appearance, they shouldn’t be used in the main content area of a window.
Make every toolbar item available as a menu command. Since the toolbar is customizable and can be hidden, it shouldn’t be the only place to find a command. Conversely, it doesn’t make sense to provide toolbar items for every menu item because not all menu commands are important enough or used often enough to warrant inclusion.
Provide a short, descriptive label for every toolbar item. Users see these labels when they configure the toolbar to show icons and text, or text only. The best labels consist of one or two words that describe the result of clicking the item. Use title-style capitalization and no ending punctuation. To the extent possible, use verbs and verb phrases like View, Insert, and Share.
For developer guidance, see NSToolbarItem.
Appearance
Make sure the meaning of each toolbar item is clear. People shouldn’t need to experiment or wait for a tooltip to figure out what an item does. Provide a simple, recognizable icon and a short, descriptive label.
Prefer system-provided icons in toolbar items because they’re familiar. Because system icons are template images, they automatically receive appropriate coloring and react to user interactions and vibrancy. See System Icons.
Prefer icons over text in toolbar items. In a customizable toolbar, labels appear beneath toolbar items when the user chooses to display them. Seeing control text above label text is repetitive.
If you must display text within a control, make sure it’s clear and concise. When describing an object, setting, or state, use a noun or noun phrase. When describing an action, use a verb or verb phrase. Use title-style capitalization.
Accurately reflect the current state of a control that toggles between two states. Sometimes, a toolbar item toggles an app state on and off. This type of item must clearly communicate its state to the user. You can accomplish this by changing the item's color scheme and label. For example, Mail includes a toolbar item that toggles your accounts online and offline. When online, the item displays a blue icon and a Go Offline label. When offline, the item displays a gray icon and a Go Online label.
Consider using translucency when content flows beneath a toolbar. Translucency creates a sense of depth and context. A toolbar automatically adopts translucency when placed above a scroll view or when the window is configured as a full-size content view. For developer guidance, see NSFullSizeContentViewWindowMask. For related design guidance, see Translucency.
Avoid giving a toolbar item a persistent selected appearance. Clicking a toolbar item results in an immediate action—such as opening a new window, switching to a different view, displaying a menu, or inserting (or removing) an object—so it doesn’t make sense to imply that there is also a change in state. The exception to this is a segmented control that shows a persistent selected appearance within the context of the control, such as the view controls in a Finder window toolbar.
Layout
Arrange toolbar items to support the main task people accomplish in your app. In general, use the leading end of the toolbar for commands that should have the highest visibility. “High visibility” can mean different things in different apps. In some apps, frequency of use should determine visibility. In other apps, it makes more sense to rank items by importance.
If appropriate, group related toolbar items. In some cases, you can define logical groups of toolbar items, such as one group for document manipulation tasks and another for text manipulation tasks. When you create a group, arrange its items according to importance or frequency of use. Use the same criteria to arrange groups themselves. The toolbar in Keynote includes several groups that are based on functionality, including one for presentation-level functions, one for playback functions, and one for object insertion.
Visibility
Let people show or hide the toolbar. A user might want to hide the toolbar to minimize distractions or reveal more content. Be sure to provide commands for hiding and revealing the toolbar should in the View menu.
Consider automatically hiding the toolbar in full-screen mode to increase the focus on content. Although people usually rely on the presence of a toolbar, you can hide it in a full-screen window if it’s not needed to accomplish the focused task. For example, Preview hides the toolbar in a full-screen window because people are more likely to viewing content than annotating it. If you hide the toolbar in a full-screen window, reveal it (along with the menu bar) when the pointer moves to the top of the screen.
Customization
Toolbars are often customizable. In a customizable toolbar, the user can decide which items appear in the toolbar, and in many cases choose whether to show the items as icons, text, or icons and text combined. Some toolbars let the user choose whether large or small toolbar items are displayed. Apps often let people hide the toolbar entirely, for increased focus on content.
In general, let users customize the toolbar. People have different workflows and should ideally be able to customize the toolbar’s contents and appearance to support their individual working styles.
Access Apps Automatically On Toolbar Apps On Mac Windows 10
Provide useful default toolbar items. Since not everyone customizes the toolbar, your default items should be commands that most people find useful. They should also educate new users about the key features of your app.
If you allow customization, add the Customize Toolbar menu item to the View menu. See View Menu.
Access Apps Automatically On Toolbar Apps On Mac ComputerBehavior
Don’t add an app-specific contextual menu to the toolbar. A toolbar already has a contextual menu that’s used consistently across the system for customization. Additionally, title bars often let people Control-click to rename a document or reveal its path. If you require a set of commands that act on the selection, either add a contextual menu in the content area of the window, or add an action pop-up button in the toolbar. For related guidance, see Contextual Menus and Action Pop-Up Buttons.
Consider letting people click nondestructive toolbar items when a window is inactive. Normally, clicking the toolbar of an inactive window brings the window to the front. In some cases, it may be useful to let the user invoke toolbar items without bringing the window to the front so they can stay focused on a task in a different window. The toolbar of the standard Fonts panel behaves this way.
Consider adding spring-loading support to toolbar items. On pressure-sensitive systems, such as systems with the Force Touch trackpad, spring loading lets a user activate a button or segmented control segment by dragging items over it and force clicking—pressing harder—without dropping the items. The user can then continue dragging the items, possibly to perform additional actions. In Calendar, for example, an event can be dragged over the day, week, month, or year segments in the toolbar. Force clicking a segment switches the calendar view without releasing the event. The event can then be dropped at the desired location in the new calendar view.
Comments are closed.
|
AuthorWrite something about yourself. No need to be fancy, just an overview. Archives
December 2020
Categories |