Transcript
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
[ 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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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?
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
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 ]