WWDC 22
What's new in AppKit
Stage Manager
New UI workflow that cleans up inactive windows in your workspace, while your active window takes center stage, letting you put the focus on one task at a time
You can also pull windows into sets that are swapped in and out as a group
This has an impact on how your app's windows present themselves:
- newly presented windows replace those on the stage to keep the workspace tidy
- auxiliary windows like panels, popovers, settings windows cohabitate with primary windows
This should mostly work as expected using existing NSWindow
APIs:
- Stage Manager won't swap out a window if it's a floating panel, a modal window, or a window with
toolbarStyle
set to.preference
- it also obeys the window's
collectionBehavior
flags (an old API from OS X 10.5-10.7 which mostly defines how a window behaves within desktop spaces, Exposé and full screen mode): a window will not displace an active window in center stage if it includes the.auxiliary
,.moveToActiveSpace
,.stationary
or.transient
collection behavior flags
Preferences
The System Preferences app now has a whole new look, with a different navigation and new design
To align with Settings apps on other platforms, it's been renamed to System Settings
If you're shipping a custom preference pane bundle, it will continue to work in the new Settings app
Your custom pane will appear in the Settings app sidebar and will be loaded on first access, like in Monterey and earlier versions
In-app settings:
To match the newly renamed System Settings app, your app's Preferences menu entry in the app's main menu is now renamed to "Settings…"
The menu item's label is automatically updated if you build the app with the latest SDK
Check your app for any other uses of the word "Preferences" in the UI referring to the preferences window and update them accordingly
New form design:
There is a new interface style for control-rich forms like the views commonly used in settings windows
It's designed to present an interface that displays a lot of controls in a clear, organized way
In this kind of UI, the form provides a lot of visual structure, so many system controls (like popup buttons) automatically adapt to this context by drawing normally with a lower visual weight and only revealing a heavier border or background on hover
You can build a form like this using the SwiftUI Form
element with an .insetGrouped
style:
Form { TextField("Computer Name", text: $name) Toggle("Screen Sharing", isOn: $screenSharing) Toggle("File Sharing", isOn: $fileSharing) Picker("AirDrop", selection: $airdrop) { ForEach(AirDropVisibility.allCases) { Text($0.label).tag($0) } } } .formStyle(.insetGrouped)
This renders Picker
as a borderless popup button, TextField
as a borderless inline text field, and Toggle
as tiny switches
SwiftUI automatically handles the visual style, layout and the scrolling behavior of such form
If you aren't using SwiftUI yet, then… well… this is a good moment to start 😅
Control updates
NSComboButton:
A combo button is a new control – a button which provides an immediate action and a menu for additional options
It combines a standard button and a pull-down menu into a single control
This design is commonly used for use cases like a "move to folder" button in Mail, which moves an email to the pre-selected folder if you click the main left part of the button (the primary action), but also lets you pick an alternative location from the menu if you click the arrow on the right side
There are two styles of the combo button which change its appearance and behavior:
- split style (the default), with a separator between the main button part and the arrow part
- unified style – looks like a normal button, performs the primary action on click, and only presents the menu if you click and hold
NSColorWell:
NSColorWell
has a new default design, with a white border and rounded corners
There are also two optional new styles you can pick:
1) A "minimal" style:
- no borders, filled completely with color
- a disclosure arrow appears on hover
- it shows a color selection UI in a popover – by default a standard system grid of colors, but you can customize what's shown there
2) An "expanded" style:
- used in iWork apps previously
- combines both interaction models: a borderless minimal style on the left, with a disclosure arrow and a popover, and a button part which shows the full color picker on the right
Select the style using the colorWellStyle
property
The behavior of the popover in "minimal" and "expanded" modes is configured through a new target-action pair: pulldownTarget
+ pulldownAction
(if nil, then a standard system popover is used)
→ you can use this to present a custom popover, or a completely different UI like a menu
Toolbars:
There are two new delegate methods of NSToolbar
that let you customize the toolbar behavior:
1) toolbarImmovableItemIdentifiers(_:)
- defines a list of toolbar items that the user shouldn't be able to move or remove (they also don't animate when you enter the toolbar editing view)
- used e.g. in Mail app for a filter button that should always appear above the messages list
2) toolbar(_:, itemIdentifier:, canBeInsertedAt:)
- allows you to manually approve any reordering, insertion or removal of a toolbar item
- use this to implement a custom set of toolbar customization rules, e.g. an item that has to stay within one toolbar section
Centered toolbar section:
- a new property
centeredItemIdentifiers
allows you to specify multiple centered items, which have to stay within the toolbar's center section - previously there could be only one centered item, specified using
centeredItemIdentifier
Preventing item resizing:
- if a toolbar item changes its label depending on the state (e.g. "Mute / Unmute" in Mail app), it may have to change its size and cause other nearby buttons to shift back and forth when switching
- to prevent this, you can now list all possible labels in the
possibleLabels
property of anNSToolbarItem
; the toolbar will automatically position items according to their longest possible label so that they don't have to be resized
Alerts design:
There is a slight update to the design of alerts
Alerts in macOS Big Sur and above have a new, compact layout with centered text, which is optimized for small amounts of text accompanied by a few clear choices
In general, this is how an alert should look: alerts work best with shorter text, which your users are more likely to read before dismissing the dialog
However, sometimes you really can't make the description shorter, especially when the alert is about something very important like deleting a disk volume
For these cases, there is now a new expanded look of alerts which is more optimal for longer text
The expanded style uses a wider window, horizontally arranged buttons, and left-aligned text
There is no option to enable this – expanded style is used automatically when:
- the description text is too long to fit comfortably in the compact size
- or if the alert has an accessory view that's too large to fit in a compact alert
Note: the layout variant is chosen at the time when the alert is presented, so the alert is not resized if the text is changed after it's displayed
You should still aim to reduce the length of the alert text whenever possible, but this should improve the UI for those cases when you can't do that
NSTableView performance updates:
NSTableView
is designed to efficiently handle a very large number of rows
It does this by lazily populating and reusing views as the table is scrolled
This becomes a challenge when the views have different heights, because it needs to calculate the total height of the table and the position of each row
Previously, NSTableView
did this be pre-calculating the size of each row in the table, which impacts the initial load time
In macOS Ventura NSTableView
now calculates the row heights lazily:
- row heights are calculated for rows which are in or near the scrolling viewport
- for the rest of the rows,
NSTableView
estimates the height based on the row heights that it has already measured - as the table is scrolled, the table view requests more row heights as needed and replaces the estimates with real measurements
This optimization significantly improves load times for very large tables
It's automatically used for all apps on macOS Ventura and doesn't require any changes
Note that this might affect the timing of delegate callbacks like tableView(_:, heightOfRow:)
SF Symbols
SF Symbols 4 adds more than 450 new symbols, including things like new currency symbols, household items or sports objects
SF Symbols can be used with one of 4 styles: monochrome, hierarchical, palette and multicolor
In macOS Ventura, symbols may now specify a "preferred rendering mode" – one of these styles that is preferred for this specific symbol and is used automatically if not configured otherwise
You can still use NSImageSymbolConfiguration
to override the preferred style
Variable symbols:
There is a new type of symbol which represents some value or quantity, like WiFi signal strength or volume
These symbols have several versions depending on the value, with a smaller or larger part of the symbol filled or colored
You configure these symbols by providing a floating point value between 0 and 1:
class NSImage { public init?(symbolName: String, variableValue: Double, accessibilityDescription: String?) public init?(systemSymbolName: String, variableValue: Double, accessibilityDescription: String?) }
If the symbol doesn't define any thresholds depending on the value, the value is ignored
Sharing
macOS Ventura includes a new redesigned share sheet, which now looks similar to the one on iOS
It includes a list of suggested people to share with, like the iOS one
It also adds new APIs which apps can use to let the user invite their contacts to collaborate on a document
The share sheet is accessed using the existing API NSSharingServicePicker
You can still filter the list of services and add custom ones, use existing delegate callbacks etc.
If you share a file URL, the sheet will automatically display the file name, type, size and icon in the header
If you're sharing a custom item, you can manually provide details to be displayed in the header using a new protocol NSPreviewRepresentableActivityItem
:
protocol NSPreviewRepresentableActivityItem: AnyObject { /* The item to be shared */ var item: Any { get } /* A localized string representing the item's name or title */ optional var title: String? { get } /* A provider for a full-sized image that represents the item */ optional var imageProvider: NSItemProvider? { get } /* A provider for a thumbnail-sized icon that represents the item */ optional var iconProvider: NSItemProvider? { get } }
or the helper class NSPreviewRepresentingActivityItem
which implements the protocol:
class NSPreviewRepresentingActivityItem: NSPreviewRepresentableActivityItem { init(item: Any, title: String?, image: NSImage?, icon: NSImage?) init(item: Any, title: String?, imageProvider: NSItemProvider?, iconProvider: NSItemProvider?) }
Use the preview class if you already have all the data you need, and the protocol with NSItemProviders
if it's too performance-intensive to generate it up front
If you want to launch the share sheet from a menu, like the main menu bar or a context menu when clicking a collection view item, the share sheet API now provides a standard "Share…" menu item that you can put in any menu to display the sheet:
class NSSharingServicePicker { var standardShareMenuItem: NSMenuItem }
In case of context menus, the displayed popover will be anchored to the same view on which the context menu was shown
There's a lot more new features for managing collaboration
See more in separate talks: "Enhance collaboration experiences with Messages" and "Integrate your custom collaboration app with Messages"
1 comment:
CloClo98
Thank you, it was quite <a href="http://www.kittens.com/">usefull</a>