Improving the Full Screen Window Experience

Session 221 WWDC 2015

Full screen windows enable people to focus on the task at hand by removing extra system UI and deferring to more of the content they care about. OS X 10.11 adds new flexibility to how these full screen windows can be configured and controlled. Hear from the experts how to get your Mac app ready to take advantage of this new functionality. Learn key strategies to making your window content be adaptive depending on the space available.

[ Applause ]

CORBIN DUNN: Hi.

Welcome to Improving the Full-Screen Window Experience.

My name is Corbin Dunn.

I'm an AppKit Software Engineer.

And I'll be giving this talk today with my colleague, Taylor Kelly.

And let's jump right in to it.

So what are we going to talk about today?

First I'm going to talk about Full Screen, and I'm going to cover three sections.

I'm going to talk about adopting Full Screen and how to properly adopt it.

I'm going to talk about Title Bar Accessory View Controllers, what they are and how to use them.

Then I'm going to talk about Full Screen Tiling API to see and utilize some of the new features that you've seen in Mac OS X v11.

Taylor's going to come up and talk about flexible layout within a Split View Controller, Auto Layout, Stack View, and finally some Collection View things.

So Full Screen.

What is the purpose of Full Screen?

It's to focus your user's attention on a single task.

You can make the most of your screen real estate.

Everything extra is out of the way, and you have one window there to concentrate on.

So why did we make it a system feature?

We have it as a system feature because it's a very consistent user experience.

The way you get into Full Screen, the way you get out of Full Screen, it's all the same.

The way you navigate across spaces, etcetera.

So what is a Full Screen-capable window?

Here's an example of a window such as Safari.

And I'm sure you're aware of that you click the green button, it'll take you into Full Screen.

Once you're into Full Screen, you can mouse on up to the top of the window, and the title bar and toolbar will drop down.

And you can hit that green button again, and it can take you back out of Full Screen.

So what are the things to do to adopt Full Screen?

Hopefully you're already aware of this, but it's pretty easy to do.

You're going to specify which windows you want to be Full Screen-capable.

You're going to add a menu item for it, and you're probably going to do some extra stuff.

The extra stuff that you might want to do is auto hide your toolbar, modify your contents to take more advantage of the Full Screen space that you now have, use the new title bar accessory view controllers.

And I'm going to talk about how and why you're going to do that.

And of course, you want to work well with Full Screen tiles.

So I'm going to discuss some API that we have for that.

First of all, there are two types of windows that, or two options for windows to be in Full Screen.

Normally when a window is in Full Screen, nothing else is allowed with it.

And that window is what we call the primary window.

It's something such as your main document window for your application.

It's the thing that you can go into Full Screen with.

However, there's also another option if you've seen this.

It's an auxiliary window, and usually you don't need this.

What its purpose is if you have a window in an application that wants to be on another application's Full Screen space, it allows you to do that.

And I'm not going to talk about it.

And I encourage you to look at the AppKit release notes from a few years ago to see some details on it.

So how do you adopt Full Screen windows?

In Xcode and Interface Builder, it's very simple.

You select your window.

There's a Full Screen section.

You drop down the menu item, and you have either primary or auxiliary.

So you're going to probably want to set primary window on your primary Full Screen window.

Of course you can do it in code, and the thing under the hood of what that Interface Builder option is doing is just changing the window collection behavior, and it's adding in dot Full Screen primary or dot Full Screen auxiliary to the window to get those options into that window and make it Full Screen-capable.

Once you are in Full Screen, you may need to do different things based on being in Full Screen.

And you can check that by looking at the style mask.

It's when your window goes into Full Screen, we add the NSFullScreenWindowMask for you automatically.

And you can check that in the style mask to see if your window is in Full Screen or not and potentially do different things.

Now let's talk about automatically hiding the toolbar.

Normally if you have a toolbar in your window, it's always visible, like it's showing up here.

When you mouse on up to the top of the window, the menu bar drops down.

The title bar controls drop down.

And the toolbar is revealed.

There's an option for you to automatically have the toolbar hidden.

So when you go to Full Screen, nothing else is seen, and you get the most use of your screen real estate.

When you're mousing up to the menu bar, the toolbar is dropped down, along with the menu bar and the title bar at the same time.

It's really easy to do this.

There's a window delegate method, Window Will Use Full Screen Presentation Options, with the proposed options.

You take those proposed options, and you add Auto Hide Toolbar to it and return that.

And the toolbar will automatically be hidden.

So it's very easy to do.

So custom animations, you can create a custom animation to enter and exit from Full Screen.

We have two delegate methods to do it.

The custom windows to enter Full Screen for a window where you return an array of windows that do your animation.

And then we call you back and say, hey, start your custom animation to enter Full Screen with a particular duration.

The thing to note about these now with the way that we enter into Full Screen in Mac OS X v11, you may not get these called.

So it's important to not be dependent on these always being called and setting up state there.

Instead, there's better ways to do that, which I'll talk about in a little bit.

Okay, so that was talking about Full Screen and how to properly adopt it.

Let's move forward and go about talking about Title Bar Accessory View Controllers.

So before I talk about a title bar accessory controller, let's take a look at a window in Full Screen, and I'm going to highlight the area that is the title bar so you're aware of it.

So this is the title bar in Full Screen.

Underneath the title bar is the toolbar.

And underneath the toolbar are what we have called the accessory views.

And so you can add your own title bar accessory view controllers at this location in the window.

And the nice thing is that they can also be added when your window isn't in Full Screen.

So this is what they would look for one that's not in Full Screen.

And they're automatically managed back and forth.

To understand why this important, it's also good to understand some of the reasons that we have it.

So let's take a look at your window.

And normally, the area under the toolbar and title bar area, that's where your content is placed.

Your content's underneath it.

But as of Mac OS X v10, you can actually utilize a full content area that can extend underneath the title bar toolbar.

And so your title bar and toolbar will have a blur automatically handled for you behind it.

And you can have your Full Screen accessory view controllers for your views in this location.

So how do you get that Full Screen mask?

It's really easy.

You just add to the window style mask in its full size content view window mask, and that makes your content be full size under the title bar.

The actual API for using the title bar accessory view dontrollers, they're a very simple subclass of NSViewController.

So all the standard view controller stuff will come into play with it for how to load them.

And it adds two properties, a layout attribute and a Full Screen min height.

So I'm going to talk about those in a minute.

But let's look at a few things that the title bar accessory view controllers do for you.

Well like I said before, they will automatically blur everything behind them for you.

You don't have to do anything special.

It's automatically contained in a visual effect for you, which is what does the actual blurring.

They automatically work in Full Screen.

So when your window goes to Full Screen and out of Full Screen, they're placed in the correct location.

And the size is kind of managed for you automatically.

And we'll discuss a little bit more about that in a minute.

So let's look at the first property, the layout attribute.

So here is the layout attribute when it's set to dot bottom.

Dot bottom means your view is going to be placed below the title bar.

Its height is whatever height you've actually specified for that view in your nib or however you specified it.

And the width is automatically changed as the window is resized.

Another option is dot right.

And this is an example of Safari.

They're using the dot right option in order to add the plus button to the Safari window when it's not in Full Screen or in Full Screen.

The width is whatever width the view has specified.

And the height is automatically set to the height of the title bar or tool bar.

New to Mac OS X v11 is the ability to specify a dot left.

And with that, you can put the [inaudible] to the side of the window buttons.

So you could add something like a register button here or some other notes that you want to show to your user.

And it's another new thing to X v11.

Next we have the Full Screen min height.

Let's take a look at that property.

So the Full Screen min height.

What does this mean?

Well this property is only applicable when you're actually in Full Screen.

And this is the minimum height that's visible when you're in Full Screen.

Anything that's not shown will automatically be shown when you mouse up to the toolbar.

And I'll show you some screenshots of that in just a second.

The default body is zero.

So let's take a look at what that means.

So a Full Screen minimum height of zero.

So here's a toolbar, and now there is an accessory view controller there, but it's hidden because the height is zero.

If the height was non-zero, you would see whatever value you set always there.

And the way it's revealed by the user is you mouse up to the top of that menu bar, and the title bar is revealed.

And your Full Screen accessory view is revealed automatically with it.

So that's highlighting that location.

Now if you've used NSToolbar, you may already be familiar with Full Screen accessory view on NSToolbar.

And this new Title Bar Accessory View Controller supersedes this older API.

And so we're encouraging you to not use it anymore.

But the min height and max height properties work very similar to what's in title bar accessory view controller.

So how do you actually add them?

Well we have four methods on NSWindow.

We have an array of title bar accessory view controllers.

You can access what's attached to the window.

You can add them.

You can insert them at a particular index.

And you can remove them at a particular index.

But it's really easy to just add and remove.

And so here's what you'll typically do.

You'll call Window Add Title Bar Accessory View Controller, pass in your accessory view controller.

And when you want to remove it, you'll use our default NSViewController API, remove from parent view controller.

Which just automatically figured it out where it is and removes it.

So that was talking about Title Bar Accessory View Controllers.

Let's talk about Full Screen tiles and some new things in Mac OS X v11.

So Full Screen tiles, what's the purpose of these?

They still allow you to focus your attention or user's attention on a single task, but it just might involve multiple windows.

You get to use all that screen real estate.

So in this screen shot we have Safari, and we have reminders on the side to focus on a couple tasks at the same time.

So let's take a look at what happens when you resize the splitter, when you are actually in this mode.

Notice that as I resize, Safari's window hits a min size and Reminders hits a min size.

And it doesn't let it shrink too far for a given window.

So it has a minimum and maximum that can hit.

So I'm going to talk about how to do that and what you need to do.

But first let's talk about, well, what windows can be put into a Full Screen tile?

We will implicitly allow any window to be put into a Full Screen tile if it's resizable and it's not a panel.

So that means your window doesn't have to be Full Screen-capable.

But it could still be added as a tile to another Full Screen-capable window.

The heuristics in exactly what we do and how we determine this might change over time.

So you might want to make it more explicit.

So let's say that you have a nonresizable window that can't be put into a tile, and you want it to be able to be put into a tile.

You can explicitly add to the collection behavior Full Screen Allows Tiling to make it allow it to be put into a tile.

Similarly, you might have a window which you want to never be put into a tile.

So we determine it it could be put into a tile, but you don't want it to be.

So you can make Full Screen Disallows Tiling to prevent that.

In addition, you might have a window, you take it Full Screen, and you want it to always be alone.

You can set Full Screen Disallows Tiling on that window to have no other windows be put with it.

So now you know if a window can be allowed to be put into a tile.

Let's talk about some of the minimum, maximum sizes for that window.

Well normally, when your window is not in Full Screen, you can resize it, and it's automatically restricted by its min and max size.

And that's usually determined automatically by Auto Layout when you're using Auto Layout.

If you're using, if you're not using Auto Layout, then the window's min size and max size come into play.

And those are just explicit properties that you set in the window.

Or content min size or content max size, depending on what you're using.

Now if you're taking a window and you're going to Full Screen or you're going to a Full Screen tile, those are the values that you should just normally use.

But there might be exceptions to that rule, and so we have some more API to solve that.

First of all, let's talk about an exception to that rule and what you're doing.

So here's something that might be a little calculator application.

And its size is not resizable.

So this developer might say, okay, we're going to allow this to be put into a tile.

But when it's put into a tile, as shown here, that calculator's app height is now a lot larger than it was before, even though it wasn't resizable.

And so it needs to handle that and do something special.

You might also add extra views there to show more information to the user when it's in a Full Screen tile.

So you can dynamically do this.

And you just use some window delegate methods, Window Will Enter Full Screen.

And in this particular case, when we enter Full Screen, we're unhiding some views, changing some constraint priorities, which allow the window to actually be resized by the system when it's in Full Screen.

And it just undoes that work when it exits Full Screen.

It is important to know that you might actually get these delegate methods even if your window does not normally make itself a Full Screen primary window.

So this might be called for a tile window.

Now those windows had a particular thick size before it was in Full Screen.

But when it's in Full Screen, it sizes different.

You will probably need to tell the system those sizes when it's going to be in Full Screen.

So we have explicit API to do that.

We have a min Full Screen content size and a max Full Screen content size to do that.

You need to set these early, because if you played around with Mac OS X v11, you may notice when you click and hold in the green button, you're provided with a selection of other candidate windows that can fit into that available space.

So you as the developer need to set these min sizes early so the system can figure out what is a potential candidate for that area.

Like I said before, normally you don't need to use these.

They're pretty much automatic when your window is just normally resizable.

So that presents a dilemma.

What happens if your window has a min size that's something like 1200, and there is another window, a window B, that says hey, my size is 1300?

Well, the system is going to not allow these two windows to be together.

Their min Full Screen content size is just too large to actually make it work out.

So what do you need to do as a developer?

And for that, I'm going to bring up my colleague, Taylor Kelly, and he's going to discuss how to handle that by talking about flexible layout.

Thank you.

[ Applause ]

TAYLOR KELLY: Hello.

In this half we're going to talk about how to make your layouts more flexible, especially in terms of how narrow they can be made while in a new split view.

On the Mac platform, we have a wide variety of display sizes that your application can run on.

And with Full Screen, users are able to immerse themselves, taking up the entire display.

With split view, users are now able to bring another window into this environment to create a richer experience.

But this requires that both windows are flexible in terms of how small and large they can be sized to prevent the conflict situations that Corbin talked about earlier.

This can be particularly tight on the smaller display sizes such as the new Retina MacBook.

This has a default resolution of 1280 by 800 points.

Meaning that while in split view, each window is approximately allocated 638 points when divided equally.

If your application's minimum width is currently larger than this, users of these display sizes are often not going to be able to tile your applications.

So I'm going to talk about four techniques that you can use to make sure your windows behave nicely in Full Screen.

First, there's using Auto Layout and priorities.

Second is the new sidebar behavior with autocollapsing.

Then is using NSStackView to easily build portions of your interface with flexibility built right in.

And finally, the updated NSCollectionView with its new powerful layout support.

So Auto Layout is a constraint-based layout system we introduced in OS X Lion and iOS 6.

It lets you declare the relationships between different UI elements, such as the spacing between them or their alignment.

And this is really powerful.

Windows views are dynamically resized, such as with localization.

You can establish priorities between those constraints so that stronger ones can override weaker ones.

I'm not going to go into too many details about this.

There were two talks earlier today, Mysteries of Auto Layout Part One and Two that whether you're new or experienced with Auto Layout, had some really great content.

Instead, I want to focus on priorities through this example UI.

We have a label centered in the middle with buttons pinned to the left and right sides.

And these might be the horizontal constraints that you'd use to create that.

With just these constraints, if the view is dynamically sized, you could end up with this overlap between the label and the wide button.

It's pretty easy to fix.

You'd add a minimum spacing constraint between that button and the label.

And now when the container's resized, it can only resize far enough to where it can satisfy both that center alignment and that minimum spacing.

This is a perfect layout, except it'd be great if this view can become even more compact, eliminating that white space between the thin button and the label.

Going back, we can make this center alignment constraint be optional, meaning it can be broken by stronger constraints.

In addition, we'll add a minimum spacing between the label and the thin button to prevent overlapping on that side.

This time, the label is centered as long as possible up until it hits that minimum padding.

And if we continue to resize the container, we can break that centering in order to squeeze the most out of our layout, up to the point to where we satisfy the minimum padding on both sides.

You can get this for your constraints by just setting the Priority property.

And this is also exposed through Interface Builder.

By default, constraints are required, meaning they must be satisfied.

But anything lower than that and the constraint becomes optional.

We have some key points to help you decide what priority your constraint should be.

There's Default Low, which is a priority at which your constraint is typically weaker than most others.

There's Drag That Cannot Resize Window, which is the specific priority at which a split view divider is dragged at.

If you want your constraint to be more powerful than this behavior, you'd make your priority higher, otherwise lower.

You'd typically never make it this priority exactly.

There's also Windows Size Stay Put, which is the priority at which a window holds its current size.

And finally, there's also Drag That Can Resize Window, which the priority at which a window is dragged at.

But there's also Default High, which is another general level at which your constraint is typically stronger than most others.

So that's Auto Layout priorities.

I'm going to refer back to the concept of priorities in a few later sections.

But next I'm going to talk about NSSplitViewController.

This is a Container View Controller class we introduced in Yosemite.

It allows your children view controllers to be arranged inside of an NSSplitView and exposes the notion of NSSplitView items, which encapsulates state about those children while in the split view.

These are things like the holding priority, the collapse state, and it allows a really easy way to get animated collapses.

Last year's talk Storyboard and Controllers on OS X talked more about this and other view controller features.

But I want to focus on what's new in OS X v11.

First is the explicit concept of sidebars and the special behavior that that comes with, as well as spring loading, which is the behavior when an item is dragged within a split view that can occur, as well as several new metrics which let you declare exactly how your split view behaves during resizes.

To go through an example, here's the sidebar in Safari.

As the window is resized, once it hits a point, there's a point at which the sidebar will autocollapse, and if it's explicitly reshown while in Full Screen, it will overlay on top of the other window content.

This is transient, similar to popovers, so clicking outside of it will autodismiss it.

This is really easy to get.

You just have to use the sidebar with view controller constructor on NSSplitViewItem, or by sending the behavior to sidebar in Interface Builder.

This will give you back a split view item that you can then add to your split view controller.

And it comes with some special behaviors such as the built-in translucent material background and vibrant divider that will be introduced in Yosemite.

You no longer have to add in your own visual effect view to get this effect.

NSSplitViewItem will add and manage that all for you.

There's also the autocollapse and autouncollapse behavior that you just saw.

And with that, the overlays will in Full Screen.

In addition, a default several of the other properties, the standard value for sidebars.

So your sidebar behaved just like the rest on the system.

With this there's also a new action method on split view controller, toggle sidebar, which will animatedly collapse or uncollapse the first sidebar it contains.

This way, writing no lines of code, you can hook to a menu item to have this effect, or a toolbar button.

Another really cool behavior is spring loading.

This happens when a user has a collapsed pane on one of the edges of your split view, and they drag an item over to that edge.

We'll translate, uncollapse that sidebar and allow them to interact with it and then recollapse it once they have finished.

You can get this by just setting spring loaded to True in your split view item, and you'll get this behavior.

And this applies to both sidebars and non-sidebars.

The difference being that sidebars will default this to True.

We believe that most sidebars will want this behavior.

Next I want to talk about several new metrics that we have on NSSplitViewItem and controller.

I'm going to go through them a couple at a time.

First are minimum thickness and maximum thickness.

These directly relate to constraints that the split view item is managing on itself.

They describe how large or small this item can actually get.

Sidebars will default these to standard values.

But this is a really convenient way to set these constraints up for yourself.

Holding priority is the only non-new metric in OS X v11.

It describes the priority at which a split view items holds its current size.

In this example, sidebar is default to a slightly higher value, so it means they're less likely to resize than other items.

So as an example, when it resizes this window, all of that resize weight goes to the content area, and the sidebar stays the same width.

Going back, you might also set this up to have equal holding priorities between the two items.

If you're familiar with Auto Layout, you might recognize this as an ambiguous situation.

But NSSplitView treats this specially.

This time when you resize it, the two views sized proportionally according to how large they were before the resize.

So both views get sized a little bit larger.

That's holding priority.

The next metric is preferred thickness fraction.

This describes the ideal percentage of the split view that a split view item wants to be in.

For instance, sidebars will default to 15 percent.

When the user enters Full Screen or double-clicks on the divider, that item will snap to that preferred thickness.

It's a really easy way for them to get back to that standard value.

Automatic maximum thickness comes into play to act as a cap for all of these automatic sizing behaviors.

If that 15 percent was going to correspond to 350, it would instead be capped at 280.

Those are all of the NSSplitViewItem metrics.

There's one more metric on NSSplitViewController, which is minimum thickness for inline sidebars.

This describes the width at which the sidebars in your split view controller will autocollapse.

So sizing right up to that will leave them inline.

And any further will collapse your sidebar.

This also applies while in Full Screen, except the key difference is that when in Full Screen if it's explicitly reshown, it shows as that overlay.

This illustrates an important concept in Full Screen, where we want to avoid running the window to prevent possible conflicts with the neighbor.

It's always better to try to rearrange contents within your window than growing it.

To support some of these new features in NSSplitViewController, we've made some enhancements to NSSplitView, specifically with the arranged subviews.

Before El Capitan, all the subviews in a split view were treated as split panes.

This meant that the API to manage this was just the subview API inherited from NSView.

And this is convenient but came with two really big problems.

One is that you're not able to add subviews that you don't want treated as split panes.

For instance, dividers.

Dividers just couldn't be represented by views with this model.

In addition, you can't separate the Z-order from the arranged order of the subviews.

So your zero index subview is both the leadingmost and lowest in Z order, and there's no way to separate that.

So now in X v11 you can designate certain subviews as being arranged by the split view using new API on NSSplitView.

This API exactly matches that on NSStackView and UIStackView for managing their arranged subviews.

There's also this property, Arranges All Subviews, which by default is True, meaning that your subviews is still always identical to arrange subviews, matching that legacy behavior.

But even when you set this to False, NSSplitView still ensures that your subviews, that your arranged subviews, are always a subset of subviews.

For instance, if you add an arranged subview that's not already a subview, it'll be added as one for you.

And finally, we encourage you to begin using arranged subviews and setting Arranges All Subviews to False, because when you do, NSSplitView is now able to use views to represent its dividers, allowing for things like vibrancy and special window-dragging behaviors.

You can also control this through Interface Builder, using this Arranges All Subviews checkbox.

Upgraded nibs will have this checked at do not legacy behavior.

But new split views dragged out from the object library will have this unchecked, which is the behavior we encourage going forward.

To help investigate problems that you may be having with your split view or trying to understand how your split view is working, we've enhanced the debug description to tell you things like how it's performing its layout and what it's using to represent its dividers.

For the layout, there are few possibilities, but we recommend making sure that your split view is using constraints.

This allows it to simply describe the relationships between its split panes and interact with other constraints you have in your window.

In addition, it'll allow for automatic right-to-left flipping of your split view panes.

And with that, we also recommend that dividers begin to be represented using views for the reasons I mentioned before.

To help figure out why your split view may or not be using constraints, we've added this Debug Reason For Layout mode, which will give you a human-readable description for why it is or isn't using constraints.

The most common reason is that the delegate is overriding certain methods that are incompatible with Auto Layout.

And it'll tell you exactly which ones those are.

Whether or not it's in a window that's using Auto Layout will also determine whether it can use constraints.

And finally, if it's being used by NSSplitViewController, it's required to use constraints.

And if you've ever tried to debug some layout problem with your split view and printed out the constraints, it probably looks something like this.

It's pretty difficult to parse.

If you really want to understand you have to draw a picture.

You can't quite tell which constraints your app has added versus which constraints the framework has added.

In OS X v11, NSSplitView now gives identifiers to all of the constraints it adds.

So you can not only tell which constraints it's using, but what it's trying to do with that constraint.

You can quickly tell which constraints your application's added, or if there's some weird sizing behavior that you're not sure what's going on, you can quickly see which constraints likely deal with that.

NSStackView has similar identifiers for each of its constraints.

I want to talk about NSStackView now.

So this is a class we introduced in Mavericks that makes it really easy to create horizontal or vertical stacks of views, all using Auto Layout.

It's completely compatible with other constraints you have in your window, but it manages all of the constraints it uses to create its stack.

So you can add or remove views and not have to worry about updating those constraints.

It has built-in notions of alignment and distribution, so you can control how your views are positioned within the stack view, as well as clipping and attaching behaviors so you can control what happens when the stack views try to make smaller than the views it contains.

In addition, in X v11 we've made a series of performance improvements, decreasing the number of constraints it uses and moving from using private internal views to using NS layout guides.

And we've seen some pretty great performance improvements.

Mysteries of Auto Layout Part One talks about this and the new UIStackView on iOS as well as the awesome new Interface Builder support that we now have.

I do want to focus on the new distributions, which describe how the stack views are arranged along the stacking axis.

You can set this with the Distribution property on NSStackView.

I'm going to go through illustrations on how each one of these work.

So Gravity Areas matches the pre-X v11 behavior, where you can designate certain views as being attracted to certain edges of the split view.

For horizontal, that's leading, center, and training.

For vertical that's top, center, and bottom.

So in this case as we grow the stack view, those views will tend towards those edges.

Fill is a new behavior where the views are required to completely fill the stack view.

And using other constraints, you can determine how they grow or distribute that size.

In this example, tiny has set to the lowest tugging priority, so as we grow the stack view, it receives all of the resize weight.

Fill Equally is similar, except now stack view is adding constraints that prefers the views to be equally sized.

In this case we're adding even stronger constraints to squeeze the stack view down, and it can override these equal filling constraints.

But as we grow the stack view, those views will tend towards that equal sizing.

Fill Proportionally is similar, except here they grow in proportion to how big their intrinsic content sizes are.

So in this case, the larger views grow even larger, and the smaller views not so much.

Equal Spacing is a distribution where it's the not views that receive the additional size, but it's the spacing between the views.

In this case, as we grow, the spacing between the edges of each of the views are all made equivalent.

Equal Centering is similar, except here, it's not the spacing between the edges of the views but between the centers of the views.

With these new distribution behaviors, we think you can use stack view in even more places of your UI and really benefit from the things it brings.

Another aspect of stack views is the clipping behaviors.

So by default, stack views can be made larger or up to the minimum size necessary to contain all of their items.

But you can also set the clipping resistance priority to allow it to begin clipping its contents at that priority.

So now we can actually be made, the stack view be made smaller than its container.

Often you don't want this partial clipping of the views, but it would be better for the views to entirely be dropped off.

You can control this by setting the visibility priority for the different views.

The view at the lowest visibility priority will be completely dropped once the stack view starts to clip its views.

In this case, we're going to set it in descending order so that as the stack view starts to clip a view, it'll just completely temporarily detach off.

So in this case, the six is not visible anymore.

If the stack view grows larger again, it'll reattach those views as there's enough size to fit them.

In addition, you can get callbacks for when this detaching or reattaching happens.

So you can perhaps make adjustments to other portions of your [inaudible], such as adding an overflow menu.

Next, I want to give a quick overview of the new updated collection view, which now has feature parity with the UI collection view.

This includes reusability of items so you can have really scalable presentations of large collections with items with section support.

In addition, there's some really powerful layout support, so your collection view behaves great no matter what the size.

This includes built-in grid layout, flow layout that matches iOS, as well the ability to create your own custom layouts.

Troy has an awesome talk about this later today, What's New in Collection View.

I really recommend checking that out.

With this talk we also have Sample Code associated.

It's a photo-browsing app that shows off various features, API, and behaviors that Corbin and I talked about.

For instance, it shows up different Full Screen API, specifically the new tiling API.

We have this little standalone window that's normally required to be aspect-ratio sized and isn't Full Screenable.

However, we have made it tileable with a custom layout once it's in that tile.

It also uses the new split view controller features, such as the autocollapsing sidebar with the overlay, as well as NSStackView.

It creates this bottom toolbar using zero constraints, which is really, really awesome.

It also uses that detaching behavior so that it can be made smaller than those items and shows this little overflow menu so the user still has access to them.

It also uses the updated NSCollectionView for this little grid of photos that behaves really responsibly.

So Corbin took us through the aspects of Full Screen, such as how to adopt Full Screen into our applications.

And using title bar accessory reviews, to have those bars that live beneath the toolbar behave really great in Full Screen.

In addition, he showed us some of the Full Screen Tiling API so that we can make sure that our special case windows behave properly while in Full Screen.

And finally, some of the ways to make sure our layouts are really flexible, especially in this narrow environment, such as using the new sidebars with Split View Controller.

Auto Layout and NSStackView to build flexibility into other portions your UI.

And NSCollectionView, with its really awesome layout support.

If you have any questions, you can contact Paul Marcos.

He loves getting emails.

In addition, we have some related sessions that I mentioned earlier.

They're all passed now, but you can catch them on video.

In addition, we have some labs that are later today, well currently ongoing, and will be later on today and tomorrow if you have any questions.

Have a great WWDC.

Enjoy the bash.

See you later.

[ Applause ]

Apple, Inc. AAPL
1 Infinite Loop Cupertino CA 95014 US