Mac Developer Library Developer
Document Generated: 2015-09-09 13:16:52 -0700
OS X Release Notes Copyright © 2015 Apple Inc. All Rights Reserved.

OS X 10.11 El Capitan Release Notes
Cocoa Application Framework

The Cocoa Application Framework (also referred to as the Application Kit, or AppKit) is one of the core Cocoa frameworks for OS X. It provides functionality and associated APIs for applications, including objects for graphical user interfaces (GUIs), event-handling mechanisms, application services, document management, and text, drawing, and image composition facilities.

Some of the major topics covered in this document:

These are the AppKit release notes for OS X 10.11. Sections with changes since the WWDC seed of 10.11 are marked as “Changed since WWDC Seed” or “New since WWDC Seed” (note that this doesn’t mean the referenced feature or change is new, but just that the section has been updated or added since the initial release notes published with the June 2015 WWDC seed). Please also refer to the Foundation release notes for discussion of some other important changes in 10.11.

Release notes for AppKit from earlier releases can be found here. This includes notes about Force Touch APIs introduced in 10.10.3.

Note that even though some APIs and descriptions refer to the APIs in Objective-C, and some others in Swift, unless otherwise specified all AppKit APIs are available in both Objective-C and Swift.

Marking updated APIs in headers

New APIs in headers are marked with decorations that include references to "10_11”:
 NS_AVAILABLE_MAC(10_11), NS_AVAILABLE(10_11, <iOS Release>), NS_CLASS_AVAILABLE(10_11, <iOS Release>), NS_ENUM_AVAILABLE(10_11)
Deprecated APIs are marked with:
 NS_DEPRECATED_MAC(<Release when introduced>, 10_11) or  NS_DEPRECATED_MAC(<Release when introduced>, 10_11, "Suggested alternative”)

Runtime Version Check

There are several ways to check for new features provided by the Cocoa frameworks at runtime. One is to look for a given new class or method dynamically, and not use it if not there. Another is to use the global variable NSAppKitVersionNumber (or, in Foundation, NSFoundationVersionNumber):
double NSAppKitVersionNumber;
. . .
#define NSAppKitVersionNumber10_7 1138
#define NSAppKitVersionNumber10_8 1187
#define NSAppKitVersionNumber10_9 1265
#define NSAppKitVersionNumber10_10 1343
#define NSAppKitVersionNumber10_10_2 1344
#define NSAppKitVersionNumber10_10_3 1347
#define NSAppKitVersionNumber10_10_4 1348
#define NSAppKitVersionNumber10_10_5 1348
#define NSAppKitVersionNumber10_10_Max 1349
One typical use of this is to floor() the value, and check against the values provided in NSApplication.h. For instance:
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_9) {
/* On a 10.9.x or earlier system */
} else if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_10) {
/* On a 10.10 system */
} else if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_10_Max) {
/* on a 10.10.x system */
. . .
} else {
/* 10.11 or later system */
Special cases or situations for version checking are also discussed in the release notes as appropriate. For instance some individual headers may also declare the versions numbers for NSAppKitVersionNumber where some bug fix or functionality is available in a given update, for example:
#define NSAppKitVersionWithSuchAndSuchBadBugFix 1138.42

Backward Compatibility

One backward compatibility mechanism that is occasionally used in the frameworks is to check for the version of the system an application was primarily intended for, and if an older system, modify the behavior of some new changes to be more compatible. This is not done commonly, but in cases where bad incompatibility problems are predicted or discovered. Most of these are listed below in these notes.

Typically we detect where an application was built by looking at the version of the SDK the application was linked against. Thus, as a result of relinking your application against the latest SDK, you might notice different behaviors, some of which might cause incompatibilities. In these cases because the application is being rebuilt, we expect you to address these issues at the same time as well. For this reason, if you are doing a small incremental update of your application to address a few bugs, it's usually best to continue building on the same build environment and SDK used originally.

In some cases, we provide defaults (preferences) settings which can be used to get the old or new behavior, independent of what system an application was built against. Often these preferences are provided for debugging purposes only; in some cases the preferences can be used to globally modify the behavior of an application by registering the values (do it somewhere very early, with -[NSUserDefaults registerDefaults:]).

Swiftification (New since WWDC Seed)

Framework APIs in both OS X 10.11 and iOS 9 have adopted new Objective-C features such as nullability, lightweight generics, and “kindof.” These features enable API intent to be expressed more precisely and APIs to come across better in Swift.

For instance we can now indicate that nil is a valid value for the destination view when converting an NSRect between coordinate systems:
- (NSRect)convertRect:(NSRect)rect toView:(nullable NSView *)view;
and that the array returned by splitting an NSString with componentsSeparatedByString: is an NSArray of NSStrings, and it will never be nil:
- (NSArray<NSString *> *)componentsSeparatedByString:(NSString *)separator;
You will notice many API changes in AppKit and other frameworks due the adoption of these new features. When building your projects against the new SDKs you may get build warnings or errors; these are important to react to since in some cases they may point out actual issues. In addition, adopting these new features in your own code should allow better compile time detection of bugs.

Please see WWDC 2015 Session 202, “What’s New in Cocoa,” for more info on this “Swiftification” effort, as well as other changes in AppKit and Foundation.

NSCollectionView (Changed since WWDC Seed)

We’ve brought the power, flexibility, and scalability of iOS’ widely used UICollectionView to OS X 10.11. The new and substantially improved NSCollectionView can present heterogeneous collections of variable-sized items, allows for completely customizable layout, supports sections with optional header and footer views, and recycles and lazily instantiates items to enable scaling to large numbers of objects. For optimal performance, it is designed to be layer-backed, so be sure to run with “wantsLayer” set to YES on the CollectionView’s enclosing NSScrollView or an ancestor view.

To use NSCollectionView’s new API model, you specify a layout by setting an NSCollectionView’s “collectionViewLayout” property, and either provide a “dataSource” or bind your CollectionView’s “content” to an NSArray or NSArrayController (see “Binding Content to an NSCollectionView”, below). You must also disconnect and discard the NSCollectionView’s “itemPrototype”, which is a vestige of the 10.10-and-earlier API model.

Independently of whether you provide a dataSource or use the “content” binding, you can bind properties of your item view subtree’s controls to properties of the item’s representedObject.

The new “NSCollectionViewFlowLayout” class will be familiar to developers who’ve used UICollectionViewFlowLayout on iOS. It provides flexible layout of CollectionView items into rows or columns, and can accommodate items of variable size. Most clients can achieve their desired results using Flow layout, by adjusting its flexible parameters, implementing delegate methods, or if necessary subclassing. Completely developer-defined layouts are also possible, however, by subclassing either NSCollectionViewFlowLayout (advisable if the desired layout is similar to Flow) or its abstract base class, NSCollectionViewLayout.

To allow for optional grouping of items into sections, NSCollectionView uses the same two-level (section,item) indexing model as UICollectionView. A CollectionView’s content is composed of an ordered list of sections (one, by default), each of which contains an ordered list of items addressed by integer index within its containing section. Each (section,item) index pair that constitutes an item designation is encapsulated in an NSIndexPath, and existing NSCollectionView APIs that deal in single integer indices and NSIndexSets thereof have been replaced with uses of NSIndexPath and NSSets of NSIndexPaths. As on iOS, a set of NSIndexPath category methods helps with creating and examining individual NSCollectionView index paths:
@interface NSIndexPath (NSCollectionViewAdditions)
+ (NSIndexPath *)indexPathForItem:(NSInteger)item inSection:(NSInteger)section;
@property (readonly) NSInteger item;
@property (readonly) NSInteger section;
A minimal NSCollectionView dataSource implements the two required methods of the NSCollectionViewDataSource protocol. The first required method returns the number of items to show in the CollectionView. (A single section is assumed, if the delegate does not implement -numberOfSectionsInCollectionView:.) The second required dataSource method instantiates an item for a given index path. Below is a simple example of implementing these methods, producing items in the CollectionView that represent a hypothetical NSArray of model objects:
- (NSInteger)collectionView:(NSCollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return myModelObjects.count;
- (NSCollectionViewItem *)collectionView:(NSCollectionView *)collectionView itemForRepresentedObjectAtIndexPath:(NSIndexPath *)indexPath {
    // Identify the model object specified by the given indexPath.
NSUInteger itemIndex = indexPath.item;
MyModelObject *modelObject = myModelObjects[itemIndex];
    // Get an NSCollectionViewItem that will represent the modelObject in the CollectionView, by sending the
CollectionView -makeItemWithIdentifier:forIndexPath: with an identifier that specifies the kind of item we want to create.
(Some CollectionViews will contain only one kind of item. Others may wish to present some objects differently, by passing
different identifier values for different model objects.) If we name our item nib “Thing.xib”, we can simply pass @“Thing”
as the identifier, and NSCollectionView will find the nib file automatically. If you prefer to use nib filenames that differ
from your item identifiers, you’ll need to register the nibs you plan to use with your NSCollectionView, using the
-registerNib:forItemWithIdentifier: method. This enables the NSCollectionView to find the desired nib based on the item
identifier you provide.
NSCollectionViewItem *item = [collectionView makeItemWithIdentifier:@“Thing” forIndexPath:indexPath];
    // Associate the item with our model object, using the “representedObject” property that NSCollectionViewItem inherits from
NSViewController. We aren’t required to set this property, but doing so will make it easy to find the item’s corresponding
model object, and facilitates binding properties in the item’s view subtree through the item’s “representedObject”.
item.representedObject = modelObject;
    // Set up any desired state in the item’s view tree.  Alternatively, we could bind control properties
through the item’s representedObject, which we set above.
item.textField.stringValue = modelObject.title;
    // Return the item.
return item;
When you send -makeItemWithIdentifier:forIndexPath: to a CollectionView, it first attempts to recycle an unused item of the requested type, if one is available. If a new item must be created, the CollectionView attempts to create it from an NSNib or NSCollectionViewItem subclass that was registered with the CollectionView. If you follow expected naming conventions, registering item nibs with CollectionView is unnecessary. When asked to make an item with identifier “Thing”, if no NSNib or Class has been registered with that name, NSCollectionView will first search for “Thing.nib”, then for an NSCollectionViewItem descendant class named “Thing”.

An item .nib must contain exactly one top-level instance of NSCollectionViewItem or a subclass. The item’s “view” outlet should be wired to the root of a view subtree that provides the item’s visual representation. Usually you want some sort of container view, containing TextFields, ImageViews, and other controls that display the item’s content.

Item size can be determined globally for all of a CollectionView’s items (by setting an NSCollectionViewFlowLayout’s “itemSize” property), or can be varied from one item to the next (by implementing -collectionView:layout:sizeForItemAtIndexPath: on your CollectionView’s delegate).

As before, you are completely free to determine item appearance. Items in a selectable CollectionView are responsible for visually indicating whether they are “selected”. OS X 10.11 adds a “highlightState” property to NSCollectionViewItem, that should also be taken into account when determining the visual appearance of an item. You may choose to show “selection” and “highlightState” indication by drawing the item slightly differently, or (since 10.11 CollectionViews operate layer-backed) by changing backing layer properties such as backgroundColor, cornerRadius, borderWidth, and borderColor, if you wish.

NSCollectionViewFlowLayout offers the potential to show multiple “sections” of items, each with an optional header view and/or footer view. These “supplementary” views are instantiated similarly to CollectionView items, by implementing the optional -collectionView:viewForSupplementaryElementOfKind:atIndexPath: dataSource method, and using NSCollectionView’s -makeSupplementaryViewOfKind:withIdentifier:forIndexPath: API from within it. The header view or footer view may be supplied in a nib (wherein it must be the only top-level NSView) or as a Class specified by name. Sizing of the header or footer is determined by implementing the delegate methods: -collectionView:layout:referenceSizeForHeaderInSection: and -collectionView:layout:referenceSizeForFooterInSection:, whose returned size values are constrained to the CollectionView.

NSCollectionViewGridLayout, unique to OS X, encapsulates NSCollectionView’s 10.10-and-earlier layout behavior, for those who might still want to use it in conjunction with the new NSCollectionView API model. NSCollectionViewGridLayout does not currently understand sections or provide for header or footer views. NSCollectionViewFlow layout is generally recommended as a more powerful, versatile, and flexible replacement.

New since the WWDC seed: NSCollectionView’s Accessibility implementation is now wired to its new API and content model. Some further refinement is still needed, but CollectionViews now successfully advertise their items (and now sections and supplementary views) for Accessibility navigation. Keyboard navigation from item to item has also been restored.

Also new since the WWDC seed: NSCollectionView now allows for customizing the inter-item-gap drop target indicator appearance, if desired. Register a NSView subclass, or a .nib containing a single top-level view, with your NSCollectionView, using -registerClass:forSupplementaryViewOfKind:withIdentifier: or -registerNib:forSupplementaryViewOfKind:withIdentifier: with a “kind” parameter of NSCollectionElementKindInterItemGapIndicator. Then watch for -collectionView:viewForSupplementaryElementOfKind:atIndexPath: to be sent to your NSCollectionViewDataSource with NSCollectionElementKindInterItemGapIndicator as the “kind”. Send -makeSupplementaryViewOfKind:withIdentifier:forIndexPath: to your CollectionView in response, passing the same identifier you registered with. NSCollectionView will use your custom view, when provided in this way, in place of its default inter-item gap indicator. Note that your view’s frame will be set to the bounding box of the inter-item gap, which might be larger than the indicator you want to draw (especially if items being dragged have been temporarily removed from the CollectionView, leaving a large layout hold behind). It’s up to you to determine an appropriate drawn size and appearance for your indicator within this bounding box, based on any knowledge you may have about the kind of layout that’s in use (Flow, Grid, or custom).

See WWDC 2015 Session 225, “What’s New in NSCollectionView,” and the accompanying “CocoaSlideCollection” code sample, for more information about configuring and using instances of the new NSCollectionView.

Binding Content to an NSCollectionView (New since WWDC Seed)

If your NSCollectionView does not need sections or supplementary views, you may use NSCollectionView’s NSContentBinding to provide the model objects you want the CollectionView to display items for. The NSCollectionView’s “content” can be bound to an NSArrayController or to an NSArray of model objects.

An NSCollectionView that displays only one kind of item can automatically infer the item nib or class to instantiate, provided you explicitly register a single item nib or class with the NSCollectionView. For example:
    NSNib *itemNib = [[NSNib alloc] initWithNibNamed:@“MyItem” bundle:nil];
[collectionView registerNib:itemNib forItemWithIdentifier:@“item”];
In this case, you do not need to provide a dataSource. The choice of item identifier is arbitrary. — As long as the NSCollectionView finds only a single item nib or class has been registered, it will know what to instantiate.

If you need to be able to display more than one kind of item in your NSCollectionView, you’ll need to provide a dataSource in addition to the content binding. Your dataSource’s -collectionView:itemForRepresentedObjectAtIndexPath: method gives you the opportunity to determine the appropriate item identifier to use when sending -makeItemWithIdentifier:forIndexPath: (just as in the non-Bindings dataSource example above). You’ll still need to implement -collectionView:numberOfItemsInSection:, since it’s a required NSCollectionViewDataSource method, but you can implement it to simply return “collectionView.content.count”. However, since you’ve used the “content” binding to tell the NSCollectionView about your model objects, you’ll find that the items returned by -makeItemWithIdentifier:forIndexPath: will have their “representedObject” property automatically set by NSCollectionView. You do not have to find the model object that corresponds to the indexPath and manually associate it with the created item. You also don’t have to explicitly register item nibs or classes when using this approach. If you prefer, you can rely on NSCollectionView to automatically.


NSPopover now takes the contentInsets of containing scroll views into account when tracking a view in that scroll view. This prevents issues such as the popover pointing to a view that is obscured by the titlebar.

NSSplitViewItem animations

Animating the collapse or reveal of an NSSplitViewItem now uses implicit animations to animate from the start state to the end state. In 10.10, it would animate the constant of a constraint.

The collapse/uncollapse animation now follows a standard timing and duration. To override the animation, set a custom animation on the NSSplitViewItem for the "collapsed" key of the animations dictionary.

Animating the uncollapse of an NSSplitViewItem will now uncollapse at a priority described by its set holdingPriority, rather than at a priority of NSLayoutPriorityRequired. This gives expected behavior, consistent with an unanimated collapse of the same item.

New NSSplitViewItem properties (Changed since WWDC Seed)

NSSplitViewItem has several new properties that describe the metrics associated with that item:

    •    minimumThickness and maximumThickness describe the minimum and maximum width or height of the item, and directly relate to .Required priority constraints managed by the NSSplitViewItem; setting these to NSSplitViewItemUnspecifiedDimension will cause no enforced minimum or maximum by the receiver, though the effective minimum and maximum could be determined by other constraints in the view hierarchy.
    •    preferredThicknessFraction describes the ideal percentage of the containing NSSplitView that that item takes up. This is used to return the item to that ideal fraction when the user double clicks on a neighboring divider or takes the containing window fullscreen. This does not influence how the item grows or shrinks as the split view does (the holdingPriority is responsible for that).
    •    automaticMaximumThickness describes the maximum thickness to which the item can be automatically resized. This affects the item when proportionally resized with the containing split view, or when the preferredThicknessFraction is used to size the item (double clicking on neighboring divider, entering fullscreen). Note this is not used as an absolute maximum, so the user or other constraints could still resize the item larger. Setting this to NSSplitViewItemUnspecifiedDimension will not enforce any automatic maximum.
    •    collapseBehavior describes the behavior that occurs when the item collapses and uncollapses: such as if its the containing split view (and potentially window) or the sibling items that get resized as a result. For instance, a collapseBehavior of .PreferResizingSplitViewWithFixedSiblings will attempt to the neighbor items at the current size and position on screen, typically growing the item out of the side of the window, falling back to resizing the items only if there's not enough space on screen or when in fullscreen.

When the first or last NSSplitViewItem is collapsed, if springLoaded is set to true, it will transiently uncollapse into an overlay when the user drags and hovers on the edge of the split view where the item is collapsed. Once the drag session ends, it will re-collapse. This defaults to false but should be used for collapsible items that contains drag targets, such as sidebars.

NSSplitViewItem sidebars and content lists

Sidebars in 10.11 have new behavior of automatically collapsing when the window is made smaller, and showing as overlays when at these small sizes in fullscreen. To make the notion of sidebars explicit, NSSplitViewItem has a new class constructor +sidebarWithViewController:. Sidebar SplitViewItems have the following behavior and defaults:

    •    Visual effect material background. The item's set viewController's view should not contain its own NSVisualEffectView background. NSSplitViewItem will manage this background view, ensuring a standard material for both Aqua and Dark appearances, as well as changing the EffectView's blendMode to .WithinWindow when overlaid.
    •    Vibrant divider. Similarly to the material background, neighboring dividers of sidebars are vibrantly blended with the same material as the sidebar background.
    •    Auto-collapsing and -uncollapsing on containing SplitView size changes (see -NSSplitViewController.minimumThicknessForInlineSidebars)
    •    The ability to overlay at small containing SplitView sizes when in fullscreen
    •    .minimumThickness and maximumThickness default to standard minimum and maximum sidebar sizes
    •    .preferredThicknessFraction defaults to the standard fraction for sidebars
    •    .holdingPriority defaults to the standard for sidebars. In 10.11 this is higher than the default holdingPriority, though not guaranteed in the future.
    •    .canCollapse defaults to YES
    •    .springLoaded defaults to YES

automaticMaximumThickness does not default to an explicit value for sidebars, but it should be set to the thickness at which the content is fully visible but tightly fitted (e.g. when any text stops truncating).

NSSplitViewController's minimumThicknessForInlineSidebars describes the size at which sidebars automatically collapse when made smaller, and uncollapse when made larger again. Note that if the split view is not able to made smaller than the set thickness, sidebars will not automatically collapse. When set to NSSplitViewControllerAutomaticDimension, the default, this will use the constraints in the window to determine the size for auto-collapsing. Once the SplitView can't be made any smaller during a live resize, it will auto-collapse any sidebars. Once the split view has grown large enough to where it can completely uncollapse the sidebar, it will do so. Setting an explicit size is better for performance and ensures a more consistent experience.

NSSplitViewController also has a new action method: -toggleSidebar:, which can be used to easily and animatedly collapse the first collapsible sidebar item. For instance, a main menu item can be used to toggle sidebars in the active window by setting -toggleSidebar: as its action and using nil / the first responder as its target.

Content Lists are a similar concept that has been made explicit in 10.11, with +[NSSplitViewItem contentListWithViewController:]. These are meant to be used with split panes that show a list of contents, such as Mail's message list, Photo's collection list of photos, etc. They have the following defaults:

    •    .minimumThickness defaults to the standard for content lists. Content lists do not have any standard maximum.
    •    .automaticMaximumThickness defaults to the standard absolute size for content lists.
    •    .preferredThicknessFraction defaults to the standard fraction for content lists.
    •    .holdingPriority defaults to the standard for content lists. In 10.11 this is higher than the default holdingPriority and less than that of sidebars. This is not guaranteed to stay constant in the future.


NSSplitView.debugDescription now returns a description with details on how the split view is configured:
    •    Its delegate
    •    The technique it uses to layout: "constraints"/"resizeSubviews"/"resizeSubviews-autoResizingConstraints"
    •    How dividers are drawn: "views"/"layers"/"drawRect"/"notDrawn"
    •    The value of arrangesAllSubviews

In order to make the layout as flexible as possible, we recommend making sure the layout technique is "constraints". NSSplitView.debugReasonForLayoutMode will return the reason the receiver is using the layout technique it is. A common reason SplitViews cannot use constraints is that their delegate implements one of the following NSSplitViewDelegate methods:

    •    -splitView:constrainMinCoordinate:ofSubviewAt:
    •    -splitView:constrainMaxCoordinate:ofSubviewAt:
    •    -splitView:resizeSubviewsWithOldSize:
    •    -splitView:shouldAdjustSizeOfSubview:

These methods are incompatible with auto layout and are discouraged. You can achieve their effects and more with auto layout constraints.

NSSplitView Arranged Subviews

In 10.11, NSSplitView has the option to not arrange all of its subviews as split panes. By setting arrangesAllSubviews to NO (it defaults to YES), the split view is in a mode where a view added as a subview is treated as standard subview with no implications for its layout. In order to make a view be an arranged split pane, it needs to be added with -addArrangedSubview: or -insertArrangedSubview:atIndex:. Adding an arranged subview will also add that view as a subview if it wasn't already. With this, arrangedSubviews is always a subset of subviews. See header documentation for more details about the effect of setting arrangesAllSubviews and the value of arrangedSubviews.

Setting arrangesAllSubviews to NO will allow AppKit to use specialized views for the dividers, rather than drawing it on the SplitView itself. In this case, the split view now returns YES for -mouseDownCanMoveWindow, and only the divider views return NO.

NSSplitViewController objects set arrangesAllSubviews to NO by default for their owned NSSplitView.

NSStackView (Changed since WWDC Seed)

NSStackView has had a significant under-the-hood overhaul. It creates significantly less constraints to accomplish its layouts, as well as removes private views from its view hierarchy, using NSLayoutGuides where needed instead. Now, added arranged views are direct subviews of the stack view, whereas there had been an intermediate view in 10.9 and 10.10. The constraints created by NSStackView all have identifiers to aid in debugging layout issues.

NSStackView has new distribution behaviors that describe how views are aligned in the stacking axis, using the distribution property.

    •    A value of .GravityAreas matches the existing behavior where views are aligned in groups along the stacking axis.
    •    Similarly .EqualSpacing matches the previous behavior of setting hasEqualSpacing to YES (which is now deprecated), where the arranged subviews fill the stack view with equal spacing between each view.
    •    A value of .EqualCentering is new behavior where the centers of the arranged views are spaced equally apart
    •    A value of .Fill is new behavior where the arranged views strongly fill the stack view along the stacking axis
    •    A value of .FillEqually is new behavior where the arranged views fill and are equally sized along the stacking axis.
    •    A value of .FillProportionally is new behavior where the arranged views fill and are sized proportionally based on their intrinsicContentSizes along the stacking axis.

New view management methods have been added to support adding arranged views with the new distribution behaviors, which do not have a notion of NSStackViewGravity for the second parameter of -addView:inGravity:: -addArrangedSubview:, -insertArrangedSubview:atIndex:, and -removeArrangedSubview:, which also correspond to the UISStackView view management methods. Using these methods to add arranged views are preferred when the distribution is not set to .GravityAreas.

NSStackView has a detachesHiddenViews property which can be set to cause hidden views to be detached from the stack view when their hidden value is YES. This also causes views that are automatically detached to become hidden rather than removed from the view hierarchy. This defaults to YES, matching the behavior of UIStackView, except for apps that are not linked against 10.11 SDK or later to match behavior on 10.9 and 10.10. Note that regardless of the value of detachesHiddenViews, the visibility priority for a view can be read/written to manage the detached views.

All added arranged views will have translatesAutoresizingMaskIntoConstraints set to NO if they had been YES. Before 10.11, it was left as-is and often led to unsatisfiable constraint exceptions if it had been YES.

Automatic detaching by using visibility priorities now reattaches views more consistently, such as in table view cells or with views who have weak intrinsic content size compression resistances.

Context Menu Callbacks

New NSView methods, -willOpenMenu:withEvent: and -didCloseMenu:withEvent:, can be used by the receiver to create visual effects for a menu being shown or dismissed against it. These will be called for contextual menus, and should be used instead of making visual changes in -menuForEvent:. They should not be used to make modifications to the passed in menu object.

View-based TableViews in Vibrant Contexts (e.g. Popovers)

In Yosemite, an NSPopover with a standard (non-source list) NSTableView with NSTextField labels would result in an incorrect appearance where the bounding boxes around the TextField would be incorrectly blended vibrantly and look inconsistent with the rest of the table view background. This is fixed in 10.11. A workaround for 10.10 is to manually set the appearance of the TableView to NSAppearanceNameAqua.

SourceList style TableViews in VisualEffectViews

In 10.11, SourceList style NSTableViews contained inside NSVisualEffectViews will inherit the containing backing rather than adding their own backing NSVisualEffectView. This containing NSVisualEffectView can be used to effectively control the blendingMode and material of the TableView's material backing. In this state, the TableView itself won't punch out content behind it, including content drawn by views between it and the containing VisualEffectView.

NSDictionaryControllerKeyValuePair changes

NSDictionaryControllerKeyValuePair is now an object rather than an informal protocol.

NSWorkspace deprecations

The NSWorkspaceLaunchOptions: NSWorkspaceLaunchPreferringClassic and NSWorkspaceLaunchAllowingClassicStartup have been deprecated. NSWorkspaceLaunchDefault has been updated to just include NSWorkspaceLaunchAsync.

The activeApplication method has been deprecated in favor of frontmostApplication.

The mountedLocalVolumePaths and mountedRemovableMedia methods have been deprecated. Use NSFileManager’s mountedVolumeURLsIncludingResourceValuesForKeys:options: instead.

The openFile:fromImage:at:inView: method has been deprecated. The image, position, and view were ignored. Use the openURL: method on NSWorkspace.

The performFileOperation:source:destination:files:tag: method has been deprecated. Many of the file operations were unimplemented, or have replacements on NSFileManger or NSWorkspace. See the individual file operations in the NSWorkspace header for replacements.

Extended Dynamic Range support

NSScreen has a new method, maximumExtendedDynamicRangeColorComponentValue, which returns the current maximum color component value for the screen. Typically the maximum is 1.0, but if any rendering context on the screen has requested extended dynamic range, it may return a value greater than 1.0, depending on system capabilities and other conditions. Only rendering contexts that support extended dynamic range can use values greater than 1.0. When the value changes, NSApplicationDidChangeScreenParametersNotification will be posted.

An NSView can request extended dynamic range by setting its wantsExtendedDynamicRangeOpenGLSurface property to YES. If any view on the screen has this enabled, the NSScreen which the OpenGL surface is on may have its maximumExtendedDynamicRangeColorComponentValue increased. When composited by the Window Server, color values rendered by this OpenGL surface will be clamped to the NSScreen’s maximumExtendedDynamicRangeColorComponentValue rather than 1.0.

NSWindow Full Screen and Spaces restoration

In previous versions of OS X, non-fullscreen windows which used NSWindow’s encodeRestorableStateWithCoder: and restoreStateWithCoder: implementations (including those that call through to super) would, on login only, have their windows restored to the space they were on previously. In OS X 10.11, this behavior has been extended to full screen windows.

NSSearchField Cancel Button Visibility

The previous behavior was that the cancel button became visible whenever the search field had focus or had text. Now, the cancel button will only show when the field contains text.

NSSearchField Notifications for Searching

Some applications present in a special mode when performing a search. For example, Finder changes the title of the window, inserts a bar with additional search options, and filters contents accordingly. Some applications continue to present a special mode after any text entered in the search field is cleared, while other applications exit the mode when text is cleared.

In an attempt to have a consistent experience, NSSearchField will now notify when the user is searching. The user is considered to be searching starting when the first action message is sent with non-empty text. Searching ends when text is cleared. We've added a new delegate protocol which will be the vehicle for these notifications.
@protocol NSSearchFieldDelegate <NSTextFieldDelegate>
- (void)searchFieldDidStartSearching:(NSSearchField *)sender;
- (void)searchFieldDidEndSearching:(NSSearchField *)sender;
@interface NSSearchField : NSTextField
@property (assign) id<NSSearchFieldDelegate> delegate;

NSSearchField Option for Centered Placeholder

We've added a new "centersPlaceholder" property that controls whether the placeholder, magnifier search button, and search menu are centered when the search field does not have focus and does not have text. With focus, the control animates its contents to the edge.

The default value for centersPlaceholder is YES since the centered-look described above was the default in Yosemite.

With the centered-look, the only way to have an empty placeholder is to use a space, “ “, since nil or the empty string will use the “Search” default. If linked on or after 10.11, only nil will result in the default, no matter what centersPlaceholder is.

Since the search field can appear centered or not, we’ve added a “centered” parameter to the custom layout methods in NSSearchFieldCell. Note that the value will not always be the same as the search field’s focus state, nor is it the same as the new centersPlaceholder parameter which states the ability to be centered. The older NSSearchFieldCell versions remain since they may be useful to those who implement custom search fields using cells.
@property BOOL centersPlaceholder;
Defaults to YES. When set, the search field's components are centered within the control if the field is empty and does not have focus. When receiving focus, given the field is empty, the centered objects will animate to the edges of the control. When this property is set to NO, the components are always at the edge. When YES, the configuration requires wantsLayer to also be YES. When NO, wantsLayer should be NO for standard appearance but can be YES for custom drawing.
- (NSRect)rectForSearchTextWhenCentered:(BOOL)isCentered;
The rectangle for the search text-field within the bounds of the search field. Subclasses can override this method for custom layout purposes. The isCentered parameter is YES when centersPlaceholder is YES and the caller is interested in the centered appearance. It is no either when centersPlaceholder is NO or when centersPlaceholder is YES and the caller is interested in the non-centered appearance. Use this instead of -[NSSearchFieldCell searchTextRectForBounds:].
- (NSRect)rectForSearchButtonWhenCentered:(BOOL)isCentered;
The rectangle for the search button within the bounds of the search field. Subclasses can override this method for custom layout purposes. The isCentered parameter is YES when centersPlaceholder is YES and the caller is interested in the centered appearance. It is no either when centersPlaceholder is NO or when centersPlaceholder is YES and the caller is interested in the non-centered appearance. Use this instead of -[NSSearchFieldCell searchButtonRectForBounds:].
- (NSRect)rectForCancelButtonWhenCentered:(BOOL)isCentered;
The rectangle for the cancel button within the bounds of the search field. Subclasses can override this method for custom layout purposes. The isCentered parameter is YES when centersPlaceholder is YES and the caller is interested in the centered appearance. It is no either when centersPlaceholder is NO or when centersPlaceholder is YES and the caller is interested in the non-centered appearance. Use this instead of -[NSSearchFieldCell cancelButtonRectForBounds:].

NSTextField maximumNumberOfLines property for wrapping text

It’s desirable for developers to restrict the number of lines of a wrapping text field, especially when the field reflows with changes in the layout. To accommodate that, we’ve introduced a new property for NSTextField called maximumNumberOfLines.
@interface NSTextField
@property NSInteger maximumNumberOfLines;
For text that wraps (see NSCell’s lineBreakMode), this property determines the maximum number of lines to display. A value of 0 means there is no limit, which is the default, and the text fills the cell’s bounds. If the text reaches the number of lines allowed, or the height of the container cannot accommodate the number of lines needed, the text will be clipped (or truncated if truncatesLastVisibleLine is set). The value of this property also affects -[NSControl's sizeToFit], -[NSView fittingSize] and -[NSView intrinsicContentSize]. Most importantly, if the value of this property is not 1, multiple lines may be used to find the field’s intrinsicContentSize. Prior to 10.11, the intrinsicContentSize would be determined as if the maximumNumberOfLines was 1.

This is similar to UILabel’s numberOfLines property. There are important differences though (thus the name change). First and foremost, NSTextField’s version only works when the lineBreakMode is set to wrap, NSLineBreakByWordWrapping or NSLineBreakByCharWrapping, while UILabel’s functionality is also subject to other line break modes that clip or truncate. Our reasoning is that the maximum number of lines is a concept of the container and not the text model. They should be independent. Second, UILabel has an unfortunate affect that reflowing does not happen if preferredMaxLayoutWidth is set to any value, including 0, a value for us indicates no preferred width. We want to reflow the field especially when preferredMaxLayoutWidth is set to 0.

Here are some notes on maximumNumberOfLines’ compatibility with other NSCell text-related properties:
scrollable - Text wrapping only applies when scrollable is NO. So maximumNumberOfLines is only in affect when scrollable is not set.
wraps - This is a convenience that returns YES if lineBreakMode is word or character wrapping. Setting it to YES also sets scrollable to NO. maximumNumberOfLines then is only observed when YES.
usesSingleLineMode - When set to YES, wrapping is ignored, and if lineBreakMode is set to word or character wrapping, it is interpreted as NSLineBreakByClipping. maximumNumberOfLines then is only observed when NO.
truncatesLastVisibleLine - When set to YES, when text overflows its container, adds ellipses to the last visible line when lineBreakMode is set to word or character wrapping. So if the text exceeds maximumNumberOfLines text will be truncated when YES and clipped when NO.

When maximumNumberOfLines is not 1, auto layout can now change the width and height of the text field as long as maximumNumberOfLines (and preferredMaxLayoutWidth) is respected. Which means that the intrinsic, or natural, content size of a text field can now vary with the field’s container instead of being the size of the text that fits on a single line.

NSTextField intrinsicContentSize improvements (New since WWDC Seed)

Previously, unless NSTextField’s preferredMaxLayoutWidth was set to something other than 0, the -intrinsicContentSize method would measure the text field with its contents on a single line, even if wrapping was enabled. Because of this behavior, the auto layout engine would not be able to find a size for a text field that spanned multiple lines, even though doing so would produce an acceptable and aesthetically better layout.

We’ve changed things such that the autolayout engine provides a width that acts like the preferredMaxLayoutWidth for the NSTextField, allowing for a text field to reflow into multiple lines. This works only for apps linked against 10.11 that have wrapping text and a preferredMaxLayoutWidth of 0. Also, it only works if the constraints on the text field allow for content compression.

Opting out:
There are some cases where you may want to opt out of the above behavior. Here are two known scenarios:
1. The height component of intrinsicContentSize may not update correctly if the string (including attributed string) contents of the text field change such that the field’s height should change but the width should remain the same. The result is a text field that either clips or is too tall. This is a known bug and you may want to opt out using the instructions below.
2. Text may wrap and the height of the text field may increase even if the line break mode of the text field is set to truncate or clip. This can occur if you have an attributed string set on the text field. When using an attributed string, its paragraph style (which includes line break mode) takes precedence over the corresponding properties of the text field and the text field cell. Also note that the default line break mode is to wrap, which means if your attributed string does not have an explicit paragraph style set, it’s assumed to wrap.

There are a few options to opt out of the new behavior, on a per text field basis. First, if the field should only have a single line of text, turn on single line mode on the text field. You can also set the maximumNumberOfLines to 1. However, if you require more than one line, you can also set the maximumNumberOfLines property to a value that makes sense - as long as it is not 0. Another option is to set a preferredMaxLayoutWidth to something other than 0 (which you have to do in code, there is no way to do this in Interface Builder). For all these workarounds, please do them as soon to creation as possible.

When using attributed strings, remember that not specifying a paragraph style is the same as using the default paragraph style, which includes a wrapping line break mode. So being explicit with a truncating or clipping line break mode is preferable.

NSGestureRecognizer Additions

NSGestureRecognizer now has a -pressureConfiguration property, allowing an NSPressureConfiguration to be automatically set by the gesture engine. When multiple gesture recognizers are active, the most compatible behavior will be set allowing for the broadest range of input. As gesture recognizers fail or begin, this effective configuration will be updated. If all gesture recognizers fail, the configuration will revert to the underlying view's configuration or the system default, as appropriate.

NSGestureRecognizerDelegate Additions

NSGestureRecognizerDelegate now allows filtering of which gesture recognizers should be allowed to participate in an event stream. This is useful for applications which don't want to subclass a built in recognizer. For example, an application might only support rotation in part of a view. On the first event which initiates the stream, the delegate will be asked if the recognizer should be allowed to recognize with the event. If YES the event processing will continue as normal. If NO, the recognizer will be excluded from the active set. Note that the recognizer will not have received the event when the delegate method is invoked, so -locationInView: will not be up to date.


AppKit provides clients with a convenient means of performing haptic feedback for alignment guides. These are used when the user is dragging an object on the screen, and the object "snaps" to known locations on screen.

While NSHapticFeedback allows clients to perform arbitrary haptic feedback, NSAlignmentFeedbackFilter helps the client perform feedback only when necessary. Often when implementing alignment guides, an application will track which object the aligned object is aligned to. A naive implementation could perform feedback when this object changes, but there are many common cases where this will perform extraneous feedback and annoy the user. The feedback filter accepts requests to perform feedback, but takes cursor velocity, snap distance, and other heuristics into account to make sure the alignment feedback feels correct.

The feedback filter uses a prepare and commit model. The app must feed the object events so that it can track cursor state. The app then asks for alignments to be prepared, and when it has chosen one or more alignments it can ask the object to perform feedback for those alignments.

The prepare methods take 3 locations. Feedback should be performed when the item jumps on screen due to alignment, so the filter has to take the previous location and the proposed alignment location. If the filter only took these two though, an item would get "stuck" as soon as it hit a guide -- how would the controller know when to release it? So, it takes a third "fallback" location which will be used if the item should become un-stuck from the guide as the user drags away.

The prepare methods come in 3 variants. Some alignments only affect the x or y coordinates, and some affect both. As such, for any given movement a controller could have multiple prepared alignments.

For every relevant event (tracking loop matching +inputEventMask), or action from gesture recognizer:
Inform the filter of the current event (-updateWithEvent: or -updateWithPanRecognizer:)
Store where the item currently is ("previousPoint")
Move the item by the appropriate delta for the mouse movement - this may be 0.0pt or several pt,
    depending on image space transformations.
Store where the item currently is ("defaultPoint")
Determine the distance you'd like to align the item (for example, 5px up to match a horizontal guide, "alignedPoint")
If alignment filter says you may move by that distance
Perform the feedback (performFeedback:performanceTime:)
Move the item to the alignedPoint
Move the item to the defaultPoint

NSWindow Split View resize increments and aspect ratio

NSWindow's resizeIncrements, aspectRatio, contentResizeIncrements, and contentAspectRatio will be ignored when determining window size in Split View. A window should do its best to fill the entire size of the tile, and these window properties would circumvent the system's ability to size two windows side by side.

Full Screen Menu Item

AppKit automatically creates an "Enter Full Screen" menu item after the application finishes launching if an equivalent menu item isn't found. If this menu item should not be created for your app, before NSApplicationDidFinishLaunchingNotification is sent you may set the NSFullScreenMenuItemEverywhere default to NO.
- (void)applicationWillFinishLaunching:(nonnull NSNotification *)notification {
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"NSFullScreenMenuItemEverywhere"];

Force Touch Trackpad Haptic Feedback

Haptic feedback should be performed sparingly. It should be a subtle interaction with the user during key moments of user input. Additionally, in general you should only perform haptic feedback when the input velocity strongly implies that the user is specifically trying to find the key spot. Also see NSAlignmentFeedbackFilter which can do a lot of this for you in certain circumstances.

Use the NSHapticFeedbackManager to get the default haptic feedback performer. Then ask the NSHapticFeedbackPerformer to perform the feedback. Always ask for the default feedback performer as it may change based on the user's accessibility preferences and the current input device.

func performFeedbackPattern(NSHapticFeedbackPattern, performanceTime:NSHapticFeedbackPerformanceTime);

    •    .Alignment - Use when visually aligning objects. This includes re-sizing, range limits, horizon alignments, etc..
    •    .LevelChange - Use when there are discreet changes due to pressure. For example, this is used by NSButton when set to NSMultiLevelAcceleratorButton type.
    •    .Generic - Use when neither of the option options are appropriate.

It is important that the user feel the feedback at the same time the correlated UI occurs on screen. However, you should not perform haptic feedback in the middle of drawing. Instead, set the appropriate performance time when performing haptic feedback.
    •    .DrawCompleted - Use when haptic performance should occur when the next cocoa or CoreAnimation drawing completes.
    •    .Now - Use when using OpenGL or there is no correlated UI change.
    •    .Default - Same as NSHapticFeedbackPerformanceTimeDrawCompleted.

Force Touch Trackpad Configuration

By default, the force touch trackpad is configured for deep click. That is, it will force click if the user exerts sufficient force on the trackpad while the cursor is stationary This way, the user always gets feedback that they have indeed pressed hard enough for a force click even if the app doesn't respond to it. However, this is not appropriate for all UI. For example, force clicks do not occur on the menu bar, in menus, nor during pressure-sensitive drawing.

There are two ways to configure the trackpad. Both start off with the initialization of an NSPressureConfiguration object with an NSPressureBehavior.
See NSEvent.h for the list of NSPressureBehaviors and a description of each one.
    •    Preferred - Set the pressureConfiguration property on an NSView. This is the most responsive method. The pressure configuration will be applied by the system as soon as the cursor enters the view, even if your application is not responsive yet.
    •    Alternate - Call set() on an NSPressureConfiguration object. The configuration is only applied if the user is holding the mouse down, the configuration will be reset on mouse up. Note: This means that you are racing the user. In some cases, the user may perform a mouse down and up before your application even receives the initial mouse down event. This approach is best used when you absolutely have to consult the mouseDown location before determining the correct configuration.

NSDocument Deadlock Avoidance (New since WWDC Seed)

Autosave, iCloud Drive, and File Coordination introduced a great deal of asynchronous behavior to NSDocument. The APIs -performSynchronousFileAccessUsingBlock: and -performActivityWithSynchronousWaiting:usingBlock: were added to ensure that NSDocument operations, both UI-level and file-level, happened in a sensible and serial manner. Unfortunately, the current implementation of these APIs combined with NSDocument's historical reliance on the main thread have made these APIs vulnerable to deadlocks. A great deal of work has been done to understand and prevent these deadlocks.

A certain class of deadlock was identified that is caused by inappropriate use of the -performAsynchronousFileAccessUsingBlock:, -performActivityWithSynchronousWaiting:usingBlock:, and -continueAsynchronousWorkOnMainThreadUsingBlock: APIs. The following code demonstrates the inappropriate pattern:
[self performAsynchronousFileAccessUsingBlock:^( void (^fileAccessCompletionHandler)(void) ) {
    ... do some work asynchronously ...
    [self continueAsynchronousWorkOnMainThreadUsingBlock:^{
        [self performActivityWithSynchronousWaiting:YES usingBlock:^( void (^activityCompletionHandler)(void) ) {
While this looks innocuous, it turns out that if another activity was initiated prior to this code, and that activity called performSynchronousFileAccessUsingBlock: on the main thread after the above file access began, this code results in a deadlock. The above performActivityWithSynchronousWaiting:YES call above never returns (because the prior activity is still active). Also performSynchronousFileAccessUsingBlock:, whose blocking of the main thread was 'interrupted' by continueAsynchronousWorkOnMainThreadUsingBlock:, can never run because the 'interrupting' block never returns, resulting in deadlock.

In OS X 10.11, code to detect and avoid this particular deadlock has been added to NSDocument. When detected, NSDocument will log a message to the console starting with "An attempt was made to call performActivityWithSynchronousWaiting:YES within a block passed to continueAsynchronousWorkOnMainThreadUsingBlock:". The message will also print diagnostic information (the contents of _NSDocumentSerializationInfo()) to help you identify the call sites of performActivityWithSynchronousWaiting:YES, and other information necessary to understand the situation. Finally, NSDocument will automatically defer performing the activity via CFRunLoopPerformBlock() to avoid the deadlock.

If you encounter the above message during testing, we recommend avoiding this deadlock by deferring the above performActivityWithSynchronousWaiting:YES call until a future run loop cycle via CFRunLoopPerformBlock or similar API, or passing NO for the SynchronousWaiting: parameter.


NSSegmentedControls in applications linked on 10.11 or later may or may not contain subviews. Developers should not assume when enumerating subviews of an NSSegmentedControl that the subviews method will return an empty array, or that any subviews returned are only those added by the Developer or that the subviews are always of a specific class. Developers are advised to filter on view tag or identifier to find specific views they are searching for, and use respondsToSelector checks if invoking methods on random subviews of an NSSegmentedControl.

NSOpenPanel (New since WWDC Seed)

A new property has been added to NSOpenPanel:
/* Gets and sets the disclosure state of an accessory view in an NSOpenPanel.
If hiding / disclosing an accessory view is not applicable this property will
behave like a read only property.
@property (getter=isAccessoryViewDisclosed) BOOL accessoryViewDisclosed;
In 10.11, most NSOpenPanels have adopted a design that was formerly reserved only for applications which adopted iCloud Documents support and this panel design was only used if iCloud Drive was turned on in System Preferences. This note will refer to the design as the “iCloud Open Panel Design” although the design is no longer limited to applications with iCloud Documents support. The iCloud Open Panel Design introduced an NSOpenPanel behavior where accessory views are hidden by default, and an “Options” button is available in the bottom controls of the panel to disclose / hide an accessory view by user action.  To prevent unexpected UI behavior changes in 10.11, NSOpenPanels in all applications linked before 10.11 which were not already using the iCloud Open Panel Design (meaning they did not adopt iCloud Documents support) will always disclose accessory views by default. The “accessory views disclosed by default" behavior matches prior shipping OS behavior where these applications would be using the "Non iCloud Open Panel Design." If your application is linked on 10.11 or later, accessory views set on an NSOpenPanel will be hidden by default whether or not your application adopted iCloud Documents support. If you find a default hidden accessory view to be undesirable, you can use the new property of NSOpenPanel to get and set the disclosure state. It is recommended you use this property before you run or begin an NSOpenPanel. This property is not preserved between panel runs, and the value of this property is also dependent on whether an accessory view has been set, and whether the panel design supports disclosure and hiding of accessory views.

NSSavePanels do not use the iCloud open panel design and do not have disclosing / hiding accessory view functionality.  The accessory view in an NSSavePanel is always visible and cannot be hidden.

NSOpenPanel (New since WWDC Seed)

Prior to 10.11, sandboxed open and save panels always granted a sandbox extension to the result of a successfully completed panel, even if the client of the panel did not explicitly request the results via the methods that retrieve an url or urls. The pre 10.11 behavior was relied on by some client applications, which were inferring the panel results via other means. On 10.11, clients must explicitly request the results of the panel by calling the URL or URLs methods, or a sandbox extension will not be granted, and any attempt to access the resources pointed at the by the result of the completed panel will run into sandbox access restrictions. Please add calls to the URL or URLs method to your code, even if you think you already know the result.


NSLayoutConstraints will now accept instances of NSLayoutGuide as layout items. This provides an easy way to calculate intermediate view geometry without having to create dummy views. Previously, dummy views were required in order to achieve equal or proportional spacing between views.

Layout Anchors

NSView and NSLayoutGuide now provide a set of properties to aid concise creation of NSLayoutConstraints. The properties are subclasses of NSLayoutAnchor, and can be used roughly like this:
NSLayoutConstraint *constraint = [myButton.leadingAnchor constraintEqualToAnchor:container.leadingAnchor constant:10];
The factory methods are available in multiple forms to allow omission of extraneous parameters, and can be activated inline if a reference to the constraint is not needed. E.g.,
[entryField.leadingAnchor constraintGreaterThanOrEqualToAnchor:label.trailingAnchor].active=YES;


-setTag: now sets the tag value on the cell’s NSMenuItem.


NSMenu now provides a userInterfaceLayoutDirection property for explicit control of the menu content layout direction. If not specified, a menu uses the layout direction of the application. The layout direction of a menu may be set explicitly in Interface Builder.

NSApplication (New since WWDC Seed)

10.11 supports a new type of menubar behavior that hides the menubar during normal non-fullscreen interaction. The menubar shows itself automatically when the mouse moves into a hot area at the top of each display. When this mode is enabled, the NSApplication.presentationOptions property will include the NSApplicationPresentationAutoHideMenuBar value.

Prior to 10.11, the SetSystemUIMode API provided by HIToolbox, and the setPresentationOptions API of NSApplication provided by AppKit, did not allow explicitly enabling an auto-hiding menubar without also hiding the Dock. -setPresentationOptions now allows the options to contain AutoHideMenuBar without also including HideDock or AutoHideDock. To ensure compatibility with existing applications, the SetSystemUIMode API will only allow applications linked on 10.11 and later to pass the combination of kUIModeNormal and kUIOptionAutoShowMenuBar; if this combination is specified by an application linked on Yosemite or earlier, the AutoShowMenuBar option is ignored.

NSWindow / Full Screen (Changed since WWDC seed)

NSWindow will implicitly opt certain candidate windows into becoming full screen capable. An explicit full screen capable window has the NSWindowCollectionBehaviorFullScreenPrimary bit set in the window.collectionBehavior. A candidate for an implicitly full screen capable window will be a titled NSWindow that is resizable, and can resize to fit the entire screen. The exact semantics of this may change over time, and it is recommended to explicitly opt in primary document windows by including NSWindowCollectionBehaviorFullScreenPrimary in the collectionBehavior.

When in full screen, if a new window is shown the following logic takes effect: A new full screen space will be created for explicit full screen windows. For implicit full screen windows, the window will simply be shown on the current full screen space. These exact semantics may change over time.

NSWindow now supports full screen tiling (Split Screen). Full screen tiling allows two separate windows to share the same full screen space. The system will implicitly determine candidate windows for a full screen tile based on window properties, such as the window being a full screen candidate (either explicit or implicit). A window can explicitly allow or disallow itself to be tiled by including NSWindowCollectionBehaviorFullScreenAllowsTiling or NSWindowCollectionBehaviorFullScreenDisallowsTiling in the window.collectionBehavior. For example, a non resizable window may still want to explicitly allow itself to be placed in a full screen tile and would include NSWindowCollectionBehaviorFullScreenAllowsTiling. Or, a full screen capable window may want to disallow tiling; this means it will never be placed with a secondary tile window, and will always be alone when in full screen.

Once a window is allowed to be placed in a full screen tile, the system will check to see if it actually fits in a target tile for a given screen resolution. The minFullScreenContentSize is then queried, and if it fits it will be placed in a tile. In general, one does not need to set minFullScreenContentSize, and it will be implicitly determined by auto layout. If the window is not using auto layout, it will fall back to using the contentMinSize or minSize of the window. This is usually sufficient for a window that does not significantly change its layout when in full screen. However, if it does have a significant layout change, then the window can explicitly set the minFullScreenContentSize and maxFullScreenContentSize as desired. If a window wants to force allow tiling and respect any size it is given, it can include NSWindowCollectionBehaviorFullScreenAllowsTiling and set the minFullScreenContentSize to 0,0.

NSWindows in full screen will no longer get a call to constrainFrameRect:toScreen: for applications linked on 10.11 or later. Instead, the window's frame will automatically be constrained within the tile space it is allowed to be in.

NSWindow (Changed since WWDC seed)

The use of NSDrawer is discouraged. Drawers are rarely used in modern Mac apps. As much as possible, redesign your UI to avoid using drawers; if you’re creating a new app, avoid adding a drawer to the design.

In OS X 10.10.0, sheets were not offset by a custom value set for [self contentBorderThicknessForEdge:NSMaxYEdge]. In 10.11 this has been fixed for all apps.

[NSWindow windowWithContentViewController:] would always incorrectly create a class of NSWindow, even if the method was called on a subclass of NSWindow. In 10.11 this has been fixed for all apps, and applications targeting a lower OS release should not use the method unless a regular NSWindow is desired.

NSWindow's NSTitlebarAccessoryViewController now supports a layoutAttribute of NSLayoutAttributeLeft for applications linked on 10.11 or later. Prior to 10.11, more than one item with NSLayoutAttributeRight may not have been presented correctly; this has been fixed.

For applications linked on 10.11 and higher, a NSTitlebarAccessoryViewController with the layoutAttribute set to NSLayoutAttributeRight will no longer right indent toolbar items, unless the titleVisibility == NSWindowTitleHidden. This allows placing a view/button/textfield (etc) above the toolbar without right indenting the toolbar. However, for the NSWindowTitleHidden, there is still a desire to indent the toolbar on the right to leave space for the accessory view.

A borderless NSWindow with a contentView that is an NSVisualEffectView with a maskImage will correctly round the corners; previously, the corners may have been jagged. The contentView must be an NSVisualEffectView for this to happen.

Prior to 10.11, a window with titlebarAppearsTransparent=YES would not allow any views under the “virtual” titlebar area to get mouse events. Commonly this would show up in applications that place a search field in this area. This has been fixed on 10.11 for all applications.

NSTableView / NSOutlineView

NSTableView now supports a new feature dubbed “Swipe To Delete”. The delegate can implement tableView:rowActionsForRow:edge: and return an array of NSTableViewRowAction objects that represent buttons. Typically these buttons are used to delete a row, or show more information. See NSTableView’s header, and NSTableViewRowAction.h for more information.

NSTableView now has API to hide individual rows: hideRowsAtIndexes:withAnimation:, unhideRowsAtIndexes:withAnimation:, and hiddenRowIndexes. This API has been made public in 10.11, but can be used back to 10.10.2. Hiding rows may be desired when it is not possible to quickly update the datasource to represent changed data. Instead, rows can temporarily be hidden, and later deleted. Visually a hidden row looks and acts the same as a deleted row. Note that hiding a row may or may not actually set the rowView.hidden property; this is an implementation detail that may change, so do not depend on rowView.hidden necessarily being YES for hidden rows. Hiding a row that is currently selected will leave it selected; developers should un-select these rows either before or after hiding it — otherwise the user will be confused because there is a hidden row that is also selected.

NSTableView will now set the objectValue to nil for NSTableCellViews when they are removed from the table. This will help avoid unexpected references to objects when the NSTableCellViews are placed in the table's re-use queue.

NSTableView now returns the minimum frame size from the auto layout method intrinsicContentSize.

The NSTableViewSelectionHighlightStyleSourceList should now only be used when the background color has not been changed from the default color. Normally, the table adds an NSVisualEffectView to implement the blur effect, but if it detects a custom backgroundColor was set it will not attempt to do this. Previously the selection would still draw with a blur. On 10.11 the selection will now draw as a normal selection highlight style.

NSViewController (New since WWDC seed)

For applications linked on 10.11 and later, NSViewController has better Swift class name searching abilities to load the NIB. First, the full Swift class name will be searched for in the bundle and mainBundle, such as MyApplication.ClassName. If a NIB can not be found with that name, it will then attempt to search for just “ClassName”. This allows one to easily load a NIB by doing a simple view controller initialization without having to pass an explicit nibName.

NSVisualEffectView (New since WWDC seed)

NSVisualEffectView has additional materials available, and they are now organized in two types of categories. First, there are abstract system defined materials defined by how they should be used: NSVisualEffectMaterialAppearanceBased, NSVisualEffectMaterialTitlebar, NSVisualEffectMaterialMenu (new in 10.11), NSVisualEffectMaterialPopover (new in 10.11), and NSVisualEffectMaterialSidebar (new in 10.11). Use these materials when you are attempting to create a design that mimics these standard UI pieces. Next, there are specific palette materials that can be used more directly to create a specific design or look. These are: NSVisualEffectMaterialLight, NSVisualEffectMaterialDark, NSVisualEffectMaterialMediumLight (new to 10.11), and NSVisualEffectMaterialUltraDark (new to 10.11). These colors may vary slightly depending on the blendingMode set on the NSVisualEffectView; in some cases, they may be the same as another material.

Prior to 10.11, the material NSVisualEffectMaterialTitlebar would slightly round the top edges of the view (applying corners). This has been fixed for applications that use the material in locations other than the top of a window.

NSApplication (New since WWDC seed)

NSApplication will now crash on uncaught exceptions for applications linked on 10.11 and higher. It is highly recommended to test applications with the default: “-NSApplicationCrashOnExceptions YES” , as this enables the behavior without having to be linked on 10.11 and allows developers to catch problems.

Unification of AppKit and CoreAnimation display cycles

AppKit deferred layout and display now occur at the same time as CoreAnimation deferred layout and display. AppKit layout and drawing operations between +[NSAnimationContext beginGrouping] and +[NSAnimationContext endGrouping] will be treated as an atomic unit (this also applies to +[CATransaction begin] and +[CATransaction commit].) This can be used in place of NSDisableScreenUpdates and NSEnableScreenUpdates. The use of these two functions is discouraged. Likewise, it should no longer be necessary to use +[NSWindow disableScreenUpdatesUntilFlush] (its use is also discouraged.)

NSColorList (New since WWDC Seed)

NSColorLists now conform to NSSecureCoding and can be securely unarchived. We encourage you to support NSSecureCoding in any custom subclasses of NSColor you may have in your applications.

TextKit for OS X

Mac OS X 10.11 introduces all the functionalities added to iOS TextKit including the exclusion paths, the maximum number of lines restriction, CGGlyph-based NSLayoutManager API, detailed layout controls via NSLayoutManagerDelegate, etc. The same TextKit API is now available for all platforms.


NSFont now offers factory methods for querying system fonts with additional weights such as ultra light or heavy. +systemFontOfSize:weight: and +monospacedDigitSystemFontOfSize:weight: both take NSFontWeightTrait. It's recommended to use the 9 predefined NSFontWeightTrait values in NSFontDescriptor.h. When a weight that's not supported by the running environment, NSFont uses the following fallback logic.

The runtime version dependent behavior is designed to minimize impacts coming from future OS X introducing additional weights. To summarize the behavior:

(A) if the app is linked on the current or older SDK:
    return the system font corresponding to the next higher available weight (so for instance a request for unavailable SemiBold returns Bold)
    this makes sure that if a weight if supported in the future release, the space taken up the element will be no wider, and still fit
(B) if the app is linked on a future SDK:
    return the system font corresponding to the next lower available weight (so a request for unavailable SemiBold returns Medium)
    this makes sure that an element ends up taking space no wider than what it does when run on the future system

The system font APIs (i.e. +systemFontOfSize:) now returns a font instance with proportional digit glyphs. +monospacedDigitSystemFontOfSize:weight: provides access to monospaced digit glyphs.

The API in the WWDC 2015 seed is not behaving as described above, yet.


API related to NSFontDescriptor and NSFontCollection provided by NSFontManager is formally deprecated. NSFontManager is now focusing to its main task for managing text attributes of the selected object.

-[NSFontManager sendAction] was incorrectly declared as a property in previous Mac OS X releases. It is corrected and now back to be an instance method.

-fontManager:willIncludeFont: is formally deprecated. It was never implemented on Mac OS X. Developers seeking a way to filter fonts displayed to users should use NSFontCollection.


-[NSTextFieldCell dealloc] no longer invokes -[NSNotificationCenter removeObserver:] with itself. That behavior had a side effect of implicitly unregistering for any notification observer registered by subclasses. Now, it is the responsibility of subclasses to properly unregister.


-[NSTextView insertText:] is now formally deprecated. -insertText:replacementRange: from NSTextInputClient should be used as the overriding point for customizing text input behavior.


NSCharacterShapeAttributeName is deprecated. The functionality for customizing font features is available through NSFontDescriptor instead. Along with the attribute, -[NSTextView toggleTraditionalCharacterShape:] is deprecated.

Dynamic Tracking (available for OS X and iOS)

The dynamic tracking is a text feature, typically for UI elements, that a single line title attempts to tighten inter-character spacing/tracking for fitting into a narrower space before truncation. It's controlled by a new NSParagraphStyle property, -allowsDefaultTighteningForTruncation . The behavior is similar to OS X feature controlled by -[NSParagraphStyle tighteningFactorForTruncation]. The main difference is that the range of ratio between the line and available space is automatically determined for the API clients (based on information coming from fonts) with the new text feature unlike the existing API controlling the ratio explicitly.  -tighteningFactorForTruncation!=0.0 enables the existing tightening behavior when -allowsDefaultTighteningForTruncation state=YES with binaries linked with Mac OS X 10.11 or later SDK. For pre-10.11 binaries, -tighteningFactorForTruncation is always preferred regardless of -allowsDefaultTighteningForTruncation value. Also, explicitly setting 0.0 to -tighteningFactorForTruncation has a side effect of disabling -allowsDefaultTighteningForTruncation. -allowsDefaultTighteningForTruncation is YES by default for apps linked against Mac OS X 10.11 or later SDK. It's disabled for pre-10.11 applications and on iOS.


NSTextAlignment enums (NSTextAlignmentLeft, NSTextAlignmentRight, etc) is replacing the existing values. The old values are informally deprecated.


NSTextWritingDirection is replaced by NSWritingDirectionFormatType. NSTextWritingDirection is formally deprecated.

NSUnderlineByWordMask is replaced by NSUnderlineByWord. NSUnderlineByWordMask is formally deprecated.

-[NSAttributedString containsAttachments] is replaced by -containsAttachmentsInRange:. -containsAttachments is informally deprecated.

Document format reading methods (i.e. -[NSAttributedString initWithURL:documentAttributes:]) without NSError arguments are now deprecated.

-[NSAttributedString URLAtIndex:effectiveRange:] is deprecated. NSDataDetector is the preferable replacement.


NSGlyph and related APIs are replaced by CGGlyph-based TextKit counterparts. NSGlyphAttribute and NSGlyphInscription are replaced by NSGlyphProperty.

New CGGlyph-based API:

The API for receiving the editing notification from NSTextStorage, -textStorage:edited:range:changeInLength:invalidatedRange: is replaced with -processEditingForTextStorage:edited:range:changeInLength:invalidatedRange.

There are additional functionalities brought over from iOS TextKit. Developers can now identify line fragments that are truncated with -truncatedGlyphRangeInLineFragmentForGlyphAtIndex:. Bounding rects enumeration APIs, -enumerateLineFragmentsForGlyphRange:usingBlock: and -enumerateEnclosingRectsForGlyphRange:withinSelectedGlyphRange:inTextContainer:usingBlock:, are replacing the old NSRectArray-based APIs.

NSLayoutManagerDelegate is enhanced with more text layout customization abilities previously only available through NSTypesetter subclassing. Sophisticated dynamic capabilities such as glyph substitution, dynamic line fragment override, line break point override, are provided to NSLayoutManager delegates.

We're deprecating the screen font support formally. Applications could either provide a UI feedback to users asking permission upgrading to the floating-point font metrics or keep using the deprecated APIs.


NSTextTabStyle and corresponding methods are deprecated. +[NSTextTab columnTerminatorsForLocale:] is added for conveniently instantiating decimal tab stops.


NSStringDrawing API from iOS TextKit is introduced for OS X. NSStringDrawingContext for handling additional options along with methods taking it as an argument are added. Corresponding existing methods without NSStringDrawingContext argument are deprecated.


NSTextAttachment API based on NSData and UTI from iOS TextKit is introduced for OS X. The new API is not relying on an external NSTextAttachmentCell object and offers more flexibilities in controlling various rendering aspects of the attachment contents without requiring to subclass NSTextAttachment or NSTextAttachmentCell. For developers requiring the dynamic layout aspect of NSTextAttachmentCell, a new NSTextAttachment protocol, NSTextAttachmentContainer, can be overridden.

The designated initializer is changed from -initWithFileWrapper: to -initWithData:ofType:. The default implementation of -initWithFileWrapper: invokes the new designated initializer with nil arguments, then, sets -fileWrapper property. Applications targeted for Mac OS X releases prior to 10.11 should override both old and new designated initializers.


Matching iOS TextKit, the -containerSize property and -initWithContainerSize: are replaced with -size and -initWithSize:. We're adding a TextKit semantics for the -size property that 0.0 indicates the infinite value.
Along with the method renaming, we're moving the designated initializer to -initWithSize:. The default implementation of -initWithContainerSize: just invokes -initWithSize:.

The TextKit enhancements for NSTextContainer providing powerful container shape customization capabilities are introduced to Mac OS X 10.11, too. -exclusionPaths, -lineBreakMode, and -maximumNumberOfLines allow richer layout customization previously available only by overriding -lineFragmentRectForProposedRect:… method.

-lineFragmentRectForProposedRect:sweepDirection:movementDirection:remainingRect: is replaced by -lineFragmentRectForProposedRect:atIndex:writingDirection:remainingRect:. The layout engine invokes the former method if it's overridden. The old API along with NSLineSweepDirection and NSLineMovementDirection are informally deprecated.

-containsPoint: is now deprecated.