WWDC2013 Session 218

Transcript

X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
[ Silence ]
>> Good almost end of
the morning to everybody.
My name's Bruce Nilo, and
I make and create and fix
and break view controllers
for a living.
I assume most of you have
some passing familiarity
with view controllers.
They've been around since the
very first SDK, I believe.
They've kind of grown
over the releases.
They basically are a mechanism
where we help you create
great application flows,
where the transitions kind
of enhance what you're trying
to say in your application.
Over the releases they've
taken up functionality
like helping decide whether
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
or not a application should auto
rotate, how it should be laid
out underneath the bars,
not underneath the bars.
In iOS 7 they're going to help
the application decide what the
status bar highlight should be.
We've changed the way
layout works a little bit,
and view controllers are
going to help you do that.
Now I'm not going to talk
about any of that today.
What I'm going to do
is go back to basics.
We're going to talk about view
controllers and transitions.
And software has this
way of kind of emerging.
It kind of -- you go back to
the beginnings all the time,
and you come back with
something even better.
And that's what we've
done for you, I think,
in iOS 7 with view controllers
and custom transitions.
So enough of my intro
to my intro.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Let's quickly go over what
I'm going to talk about.
So to do transitions --
and by transitions I am often
kind of taking a shortcut.
I really mean transition
animations right now.
To do them, you need great tools
and API to do those animations.
And we have a bunch
of them already,
but we've added a whole lot
more in iOS 7, and we're going
to go through that quickly.
We're going to talk about custom
view controller transitions,
meaning how you can create
your own, and then we're going
to introduce this notion
of how you can create view
controller transitions
that are interactive.
And then we're going to
go into some other detail.
So let's kind of delve in
a little bit what I mean.
First of all, hopefully
everybody here has used the
block animation API on UIView.
We're going to quickly
review that, because a lot
of the animation tools that
we are adding in iOS 7 are
in fact enhancements
of that API.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
We've introduced kind of a
UIView block-based spring
animation API.
There's a lot of bounciness,
and kind of harmonic transitions
that you see in iOS
7, and we're going
to give you guys an
easy way to do that too.
Key frame animations.
It's been really hard to
get key frame animation
at the UIKit level, you
typically had to dive
down to do it, and we're going
to make that a lot easier too.
And finally there's
probably been a lot of buzz
around UIKit dynamics.
We're going to talk
about that a little bit,
and how it works
ultimately with transitions.
So custom view controller
transitions.
First of all, which of these --
which view controller
transitions are we
talking about?
Well there's kind of three,
maybe three and a half that are
like the big kahunas,
as it were.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Present and dismiss, you'll
be able to customize those.
Tab bar controller, tab bar
controller actually never really
had any kind of animated
transition.
Well now it will
if you want it to.
Navigation controller,
you've already seen
that we've done a bit out of the
box with navigation controller,
and you're going to
be able to customize
that as well, if you'd like.
And finally, UI collection view
controller, it was kind of thin
as a view controller
coming in on iOS 6.
We've beefed it up a little
bit, and made it work better
with navigation controller.
So now you'll be able to put a
UICollectionViewController
in with really almost
no code at all,
have your navigation controller
transitions basically be your
collection view layout
transitions.
We're going to talk about
what a transition is,
just so that we're all
speaking the same language.
There's a lot of API, and
we're going to go through it.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
There's going to be a lot of
code that doesn't fit very well
on these slides, and
I apologize for that.
Interactive view
controller transitions.
Well there's one -- actually
in iOS 6 we had UI page view
controller, and you could swipe
that back and forth,
that's an example
of an interactive
view controller,
or an interactive transition.
In iOS 7, the pop gesture
is now interactive as well.
And basically, you
guys can add your own.
We've beefed up collection
view a bit too,
so collection view
can now be interactive
in a couple of different ways.
And we're going to talk about
that, and again in the context
of how you can use it
for your custom view
controller transitions.
Interactivity introduces
an introducing twist
for a view controller
transition,
in that you can change your
mind halfway through it.
I mean you don't have to change
your mind, but the user --
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and certainly this is the case
with the pop gesture in iOS 7 --
the user might kind of
move their finger halfway,
and then say nah, I want to
be back where I started from.
And there's some
implications to that
that we're going to talk about.
To kind of help with
some of those issues,
we've introduced a brand new
object called a transition
coordinator, and as we
implemented it initially
to help deal with cancelled
transitions, it became clear
that it solved a lot of other
interesting problems too,
and we're going to
talk about that.
So let's go into the
new animation APIs
that we have to offer.
So, these two methods I
believe were from the beginning,
that's not the block-based API.
This one was introduced
I believe in iOS 4,
and if you guys aren't
using this for your kind
of UIView level
transitions, you probably want
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to take your view controllers
in for a tune-up, and your views
in for a tune-up as well.
So let's look and see
what the connection is
between this method
and core animation.
You don't really need to know
much about core animation
to use the UIKit
animation APIs, but it helps
to have a little bit of depth
to understand what's going on.
So inside of this block
-- this animation block,
you can update arbitrary
properties on your views.
Views are layer backed in UI
kit, and on iOS for that matter,
and as you update
those properties,
the various properties are kind
of updated at the layer level.
And when you're in that block,
core animation objects get added
to the layer, and that's
actually what's driving the
animations that you
see throughout iOS.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Sometimes you get caught
within of the dynamic scope
of these blocks, and
you don't expect to be.
And so we added some
API that you could --
I mean a long time ago that you
could disable and enable whether
or not you wanted the properties
that you were tweaking
to actually be animated.
This API has a little
bit of problems,
in particular I can't tell you
the number of bugs I've gotten
where somebody forgets to set
it back to the right value,
and things don't animate,
and all hell breaks out.
So we've added this
block-based API
that you can basically execute
code which will guarantee not
to animate, if it's executed
in the block that you pass
in to perform without animation.
Okay, so now to something
new, spring animations.
Great thing is you don't
have to know about, you know,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
solutions to single dimensional
harmonic oscillators.
The reality is we --
people actually kind of iterate
the values, the damping ratio,
and the spring velocities which
are two new terms, or parameters
that we've added
to some new API.
And basically we support
critically damped oscillations
to under-damped oscillations.
We don't do over-dampen.
And the API looks like this.
It looks pretty familiar, except
it has those two new parameters.
And I'm going to
show some examples
of this later on in the talk.
Key frame animations, animate
key frames with duration is
to CA key frame animation
as animate with duration is
to CA basic animation.
Yeah, I have some kids who
just go through their SATs,
so I thought an analogy
would be good.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So you specify key frames
within the animation block,
we've augmented the options to
include the calculation mode.
It can pose as great with other
UI view animation methods.
So there it goes for
your use in iOS 7.
What's a little bit different
is this add key frame
with relative start time.
The way you'd structure your
code is something like that.
Those add key frames are
actually the key frame values
of the particular
property most likely,
or they could be
multiple properties
at different points
in the animation.
Finally I wanted -- have a small
callout to the new snapshot API,
because with these snapshots,
for one thing they're nice
and efficient, but for the other
thing is this snapshot API lets
you build some really incredible
transitions, and we're going
to show some of those as well.
An interesting point to note
is when you create a snapshot,
you can create snapshots
of snapshots,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and that can also
be pretty useful.
Okay, UI kit dynamics,
it's distinct from all
of the UIView animation APIs,
it's important to understand
that because there's
some kind of tricks --
or not tricks, but helper --
there's a helper class that we
offer that really only works
if your transition -- if your
custom transition is using the
UIView animation API.
We're going to talk
about this a lot more
in this morning's advanced --
in this afternoon's advanced
dynamics talk, so I invite you
to that if you find
this stuff interesting.
Okay, first of all I want to --
the room to take a deep breath.
This stuff is really
easy to use.
A lot of people that
I've showed it
to get a little bit
confused, but it really is.
So first of all,
presentations and dismissals.
You can customize your
full-screen presentations,
but we added a new
modal presentation type,
which is presentation
custom, fancy that.
And the difference with --
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
about that is that it
actually doesn't remove the
from view controller from
the window hierarchy.
So you can actually build your
own kind of form sheet type
of presentation if you
wanted to on the phone.
I'm going to show
you an example --
a few examples of that actually.
So that's what it is.
We're going to talk about
the new things in a bit,
but really you set
your presentation type,
you create this new little
delegate object that you assign
to the view controller
that you're presenting,
and you call present view
controller, and you're done.
That's it.
Tab bar controller,
there's actually nothing
to change there.
You're just going
to set a delegate
that vends [phonetic]
the right object.
Same with navigation controller.
So I'm giving you the
programmatic variance of this,
but of course if you hit
buttons that effectively call
into these code pads, you will
have your custom transitions
for both navigation controller
and tab bar controller.
So I mentioned about
navigation controller
and collection view controller,
we can refer to those as layout
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to layout navigation
transitions.
Basically all you need to do is
set that one property to yes,
and push your view controllers.
And all of the view
controllers that you push
or pop will actually
be transitioning,
using set collection
view layout.
So that's pretty cool.
So I'd like to take a minute
to show you guys a small
demo app I wrote --
nod to the demo Gods to
hope that it actually works.
Oh look at that.
Demo Gods are kind.
So here we have this kind
of pretty simple app,
it's kind of Ansel Adams'esque,
and this was done even before I
knew we had a California theming
thing going on.
That's Yosemite in
the background.
Basically, unless
I say differently,
every transition you're going to
see here is a custom transition.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So let's do the slide.
Now you might think hey,
that's just a normal push.
Well, look at the
navigation bar.
There's a trans -- there's
kind of a cross fade.
Any custom transition with the
navigation bar is actually going
to -- I mean with the navigation
controller is actually going
to do a cross fade on
the navigation bar.
To highlight what
I am talking about,
I'm going to change the edge
that we're going to go to.
I might be doing this too fast,
but I'm going to change it
to come in from the top.
By the way, let me also
point out, you see that view
that just got presented?
That was a custom presentation.
So it has the backdrop,
the dimming view,
it's kind of a slow
form sheet on a phone.
So if I do the slide again, oop
I'm coming down from the top.
So all this is pretty
straightforward.
Let's look at bouncing.
So this is a spring
animation, and I want you
to notice it's kind of a
under-damped coming in.
You'll notice a little kind of
bounce that comes in and out
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
of that, and then it's
critically damped going out.
If we change the
damping ratio here
to make it a little bit
more bouncy, you're going
to see what happens,
that it's going to kind
of overshoot and bounce.
And so you can change these
parameters as you like,
and get different types
of spring effects.
And they're pretty performant.
So for simple types of bounces,
you don't really need to go
into UIKit dynamics
as an example.
So now let's look at
key frame animations.
I'm going to show you two
demos on key frame animation,
but the first one I
call the foldout thing,
and that's using snapshots
and key frames to do kind
of an interesting
fold push or pop.
I can actually make that work
on a presentation as well,
and this is the exact same code,
I'm just setting
different delegates.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And the code that you've written
for your transitions
is just going to work,
whether it's a present, a push,
tab bar controller
select, etcetera.
So now I'm going to jump
to something a little
bit different.
I'm going to do a
collection view thing.
Now this was a standard
transition.
You'll notice if I hit the
-- kind of slide it out,
notice how the navigation bar's
kind of doing that slide thing.
That's the default
navigation bar transition,
and this is the built-in
pop gesture on iOS 7.
But now what we have is we have
the collection view controller
that we pushed in.
And when I tap on
one of these squares,
I'm going to push another one.
And you'll notice
that we're still
in the navigation controller,
and we've changed
view controllers,
but the navigation bar now works
with your collection
view layout.
And what's interesting is the
built-in pop gesture works too.
You get that for free.
So I'm not going to talk
much about UIKit dynamics,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
but I do want to
whet your appetite
for this afternoon's talk.
So here we go, here's
a drop animation.
This is a dialog that comes in,
and give you something
nice to know.
You notice how it came in,
it bounced a little bit,
and now I want to dismiss it,
and [laughter] I'm not saying
that's good UI [laughter], but,
you know, it's kind of cool.
Okay, so let's talk a little
bit about how to do this.
Transitions.
I'm going to -- this is
kind of a stylized rendition
of a push transition on
a navigation controller.
The blue is the view hierarchy,
the yellow is the view
controller hierarchy,
and basically the
definition of the start state
and the end state,
'cause the transition
between states is the
view controller hierarchy
and the view hierarchy,
they're consistent.
Now to move from one to the
other, you go through this kind
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
of inconsistent phase.
And so basically now
we have, you know,
we have the child view hierarchy
that's a little bit different
than the view controller
hierarchy,
and we're in -- we're
transition.
And part of a transition
is to animate,
and you add child B's view in,
you do whatever snazzy
animation you want.
Things are looking good.
They're not -- you're not
fully consistent yet though
until you do something else,
because we have a lot of things
that need to get wired
up again in terms
of our internal data
structures and the like.
So, the states are consistent
view controller hierarchy
and view hierarchy,
you transition programmatically
hitting a button,
and there's a few things
that we do to figure
out where you should
start, where you should end,
and what you need to do to
finish, and basically that's it.
So that highlighted --
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
those highlighted statements
are what we've reified
into a new system object.
And this system object is going
to be pretty critical for you
when you're building
your custom transitions.
It's called UI view controller
context transitioning.
We have a competition
in UIKit to come
up with the longest names.
I'm a contender, but
I haven't won yet.
And so this transitioning
object has some interesting bits
of information.
One is the view in
which you animate,
that's an important thing
to know, the other is
where you started from,
where you're ending.
It's important to
actually start and end
from where the system
wants you to start and end.
And then there's this method
called complete transition.
It's kind of a callback
that you do at the end.
And if you don't do that,
we're not going to be back
into a consistent state.
So this object that gets passed
into a number of our other --
a number of the objects that
you are going to create and vend
to create your custom
transitions needs
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to call back into that method.
So this is one of the objects
that you will be creating.
It will be any object that
conforms to this protocol,
UI view controller
animated transitioning.
There's two required methods,
you've got to tell it how
long is this transition going
to take, and then you've got to
implement animate transition.
And you'll notice that
it's passed in one
of those context objects.
So let's go back to the
intermediate step here.
So what's going to happen is
the system is going to call you.
You've done push view
controller, the system is going
to call you at some
point and say okay,
animate your transition.
You're going to put your
child view controller's view
into that parent container view,
do your fantastic
animation using all
of those new UI view animation
APIs, and then at the end
of the day when the
transition is done, you're going
to call the context complete
transition, and you're back
into a consistent state.
That's really it.
I'm going to go through
this a few different times
and a few different
ways, so that we'll try
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to demystify some of this stuff.
First of all, you vend these
objects with delegates.
There's a new transitioning
delegate protocol
that we've added, and we've
augmented the navigation
controller and tab bar
controller delegate.
And those delegates are going
to vend these animated
transitioning objects,
as well as an interactive
transitioning object,
which we're going to talk
about in a few minutes.
I'm pushing kind
of interactivity
to the side right now.
And all of these are
pass at context object,
and that's a system object.
You are most likely not going
to ever have to create an object
that conforms to the context
transitioning protocol,
however you do need to
create objects that conform
to those other protocols.
So let's look at this again.
As I said, I'm going to do this
a couple of different ways,
because I've been informed
that it can be confusing.
So first of all, you set
the transitioning delegate.
I'm kind of walking
through what do you do
for a custom presentation.
You say present view controller.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
The system is going to ask your
delegate, if you've set one,
do you have an animation
controller for me to use?
And if you have implemented
that method on the delegate,
and you vend one of these
objects, then we're going
to do something slightly
different.
We're going to ask you at some
point how long is the transition
going to take, and we are going
to call animate transition
on your object, passing
in one of these contexts.
Finally when your
animation is done,
you call complete transition.
Got it? Complete transition.
You don't call complete
transition,
and you'll be unhappy.
Okay. Let's look at it
slightly differently,
let's look at it as code.
Code, this kind of
looks pretty standard.
You set the delegate, you
set the presentation style,
you're off to the races.
You present.
This is code that
gets a call back.
This is not within the same
dynamic scope necessarily,
but we're going to call
back into you asking you
for the animation controller.
At some point later we're going
to say animate, transition,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and this is your code.
You're going to basically
implement that method
on your object that conforms
to the animated transitioning
protocol, you're going
to add the sub-view into the
container view, you're doing
to do some great animation.
And then one standard technique
is in the completion block
of the animate with
duration method,
you will call complete
transition.
Okay. So let's look a little
bit at some of these new APIs.
They're really, you know,
you can look at the docs,
you can look at the
header files,
but these are pretty
straight forward.
These are -- this is the new
transitioning delegate protocol.
The same thing for the
animation controller goes
for an interaction controller,
which we're going to talk about.
View controller has grown a
transitioning delegate property.
It's set on the presented
controller.
Just to make it clear, that's
kind of consistent with a lot
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
of the previous ways
that presentations
are kind of refined.
You set your values on
the presented controller.
We've grown a couple
of new methods
for the navigation controller,
again one for animation
controllers,
one for interaction controllers,
and ditto for tab
bar controller,
kind of nothing too much
to talk about there.
But the objects that they vend
have some interesting beef
to them.
First of all, they need to
implement animate transition.
And the implementation of
animate transition needs --
is -- takes responsibility
for inserting the two
view controllers view
in the container view.
That's because we don't know
what your animation is going
to be, and you might want to
put it in different places,
you might want to put it
above, below some other views.
So it's your responsibility
to do that.
You need to make sure
that the two in view --
that the to and from view
controllers' views are
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
where they need to be, and
you call complete transition.
Okay, let's talk a little bit
about interactive view
controller transitions.
Now interactive transitions
is kind of a whole new thing.
As I said, the pop
gesture is pervasive,
and probably you guys are going
to want to do something similar
with some of your
view controllers.
I've mentioned you can use
-- you can create your own.
I should also mention as an
aside that you can get a handle
on the default navigation
controller's pop
gesture recognizer.
So you can create dependencies
on it in case you have content
that perhaps you
don't want to --
that has its own gesture
recognizers that you don't want
to collide with the
pop gesture recognizer.
Interesting is that
although it might seem
that all interactive
transitions might be driven
by gesture recognizers, that
isn't necessarily the case.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
You can -- anything that you
can drive programmatically
in an iterative way can
actually be the source
of an interactive transition.
They typically go forward,
move forwards and backwards,
and they can often be cancelled
by -- they usually are started,
if they're not started we're --
we have nothing to talk about.
We provide this -- the only
concrete class that we provide
for all of this is
the UI percent driven
interaction transition.
And what's great about this is
that if you use a
UI view animation --
the UI view animation APIs in
your animate transition method,
we're going to take care of, you
know, reversing the animation,
cancelling it, doing
all that stuff.
You don't even have to call
the context transition --
the context object with
complete transition.
And so we're going to show a
couple of examples of that.
The protocol for interactive
transitioning really couldn't
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
be simpler.
Start interactive transition.
That's called instead
of animate transition
on the animation controller.
Now it doesn't mean that
you don't need an animate
transition, because
maybe your inner --
maybe your transition isn't
going to be interactive.
Moreover, your start interactive
transition is free to call
out to the animation
controller's animate
transmission, as makes sense.
Those last optional properties
are most often used for the sake
of the UI percent driven
interaction transition,
and so when the interactive
portion of a transition stops,
you can kind of tell it
to speed up, slow down,
change its timing curve to
kind of finish the transition.
So let's go to this sequence
again and see what's different
between interactive
transitioning
and just non-interactive
transitioning.
So far everything
looks the same.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
What's different is this.
In addition to asking for
the animation controller,
we ask for an interaction
controller.
If you don't provide an
animation controller,
we're never going to
ask the second question.
So you need to implement
both if you want
to implement interactive
transitions.
We're going to go through
this little picture,
because I think it's
illustrative of some
of the differences in terms
of what an interactive
transition entails.
First of all, we're
going to start
with this interactive
event handler.
I've kind of made it generic,
but let's imaging it's
a gesture recognizer.
And your gesture is going
to commence, and it's going
to say okay, this
-- I'm good to go,
start interactive transition.
And it's going to do that
by doing push, pop, present.
It doesn't call start
interactive transition.
The system calls start
interactive transition.
And once that happens, we're
going to call that method
on the interaction controller
that you vend, and now we're
in this update interactive
transition state.
And your gesture
recognizer is basically going
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to be constantly calling
update interactive transition,
based on what's going
on with your gesture.
You might be computing
a percent complete,
you can compute a bunch
of different things.
But you're going to
be driving it there.
At some point, the
gesture is going to end,
or the interactive portion of
the transition is going to end,
and for illustrative purposes,
we're going through
the finish path,
which means that we're actually
completing the transition
we started.
But you might decide to go
through a different
path altogether,
and that's the transition
cancelling up there.
We're going to call the
context finish interactive
transitioning, and then in this
particular case the interaction
controller has decided it's
going to finish the transition
by calling the animation
controller's animate
transition method.
You don't need to do that, but
it often is convenient to do so.
And in the case of UI percent
driven interactive transitions,
that's in fact what we do.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Finally, animation ends,
complete transition is called,
and you're back into
a consistent state,
and your interactive
transition is over.
So that's what's different.
I'm going to highlight
what's a little bit different
about interactive transitions.
First of all, there's
a start, which is kind
of the interactive phase,
then there's a phase
which is the transition
finishes, it's animating
in one direction or the other,
and it can either be cancelling
or finishing, and
then we complete.
So the easy way to do all
of this is, as I said,
use the UIViewController
percent driven transition,
you have to implement
animate presentation
on your animation controller,
and then your gesture
recognizer is going to drive it,
or whatever your generator for
the interactive transition is.
Typically we sub-class this.
You don't have to, but
it's useful to do so.
And instead of calling any --
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
out to any of the context
methods, you're just going
to call out to the instance of
the percent-driven transition,
how much, how complete
you are or not, or whether
or not the transition
was canceled
or completed successfully.
So, this is what percent-driven
interactive transition
looks like.
It has those three methods
that you are going to call.
And this is another demo that
I actually forgot to give,
which -- but this is an example
of a tab bar controller
interactive transition using the
percent-driven transition.
And it's kind of cool.
It's using key frame animation,
it's using the new UI
view key frame animation,
and it's implementing this kind
of accordion transition
from tab to tab.
This is the one that I showed
you, which was the fold one.
And again, this is --
the interactive portion
of this is driven
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
with the percent-driven
transition.
So that fold object, that
interactor is a sub-class
of percent-driven
interactive transition.
Those little methods in there,
those are methods that I define
to make it easy to implement.
One of the things I wanted
to know is what the navigation
controller was that I was in.
I also wanted to know if
things were interactive or not,
because I could either
transition interactively
or not interactively.
That's the code, that's it.
I've implemented a pinch
gesture recognizer.
It hangs off of that sub-class
of percent-driven interaction
transition, and all I need
to do is when the
gesture begins,
I call pop view controller,
when it continues
as the pinch moves
I call update,
I compute some percentage.
I'm doing this based on
the scale of the pinch.
And then when it ends,
I either call finish
or cancel, and that's it.
If you've sub-classed
percent-driven interaction
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
transition, you're going to
get all of your interactivity
with about that amount of
code, depending on the logic
of your interactive stuff.
So, we also do collection
view --
interactive collection
view transitions,
and we've grown the
API on collection view.
I'm going to bring
up my colleague,
who made me train a long time
to pronounce his last name.
It's probably the hardest
part of this presentation.
Olivier Gudkenesh [phonetic].
>> One year of rehearsal
almost paid off.
So I'd like to talk
about collection view.
We have very nice interactive
API in view controllers.
And what's great is we
also added a new API
in collection view to drive
interactive layout transitions.
So it's really easy to use
with a view controller API.
And that new API is
actually a new layout,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
UICollectionView
TransitionLayout.
And what that layout
implements actually is a way
to interpolate between
two layouts.
It can be interactive or not,
usually it is interactive
with a simple transition
progress property.
You can sub-class it,
which is really useful.
And it was designed to be
really simple to integrate
with interactive view
controller transitions.
How does that work?
Let's say that my current layout
in my collection
view is layout A.
The next layout is layout B.
So today in iOS 6 you could
use set collection view layout,
and you would pass yes,
and we would just animate.
If you use a UI collection
view transition layout,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
you can actually drive
that transition progress,
so at 0 it's going to be
exactly like layout A.
But if you change that value to
0.5, from a gesture recognizer
for instance, then we could
compute the interpolation
between all these cells.
And so when you drive
that to 100%,
it's going to look
like the next layout.
So you can drive back and
forth this transition progress.
And UICollectionView
can go to 11.
[Laughter] So we sometimes
have this really nice scale
up at the end of a
transition, and then scale
down back to the real value.
And we do that for free,
we do that in UI collection
view transition layout for you.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
You don't have to do anything.
And you don't even need to drive
transitional progress past 1.0.
We do that under the hood.
How does that work?
We added three new methods
in UICollectionView --
start interactive transition
to collection view layout
with a completion handler,
and I'm going to initiate
that interactive transition
to the next layout.
Then from your gesture
for instance,
you can drive the
transition progress,
because the value you
get here is an instance
of UICollectionView
TransitionLayout.
And when the gesture ends,
and you won't have to animate
to the next layout, just call
finish interactive transition,
or if you want to get back
the old current layout,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
just call cancel
interactive transition.
There is a new delegate method
in UICollectionViewDelegate,
collection view transition
layout for layout to new layout.
Why that? You might want a
different interactive transition
from layout A to layout B, but
something a little bit different
from B to C or C to D.
So you can actually tweak
and return different collection
view transition layout
sub-classes for all these cases.
This does not replace the
existing setCollectionViewLayout
animated, which is
completely automatic
and really easy to use.
Collection transition
layout is really useful is
when you subclass it.
Why? Because you can
tweak the cell positions
in the layout attributes
we compute.
Which means that you could drive
changes to cell positions based
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
on the gesture position.
What could I implement
with that?
Photos, pinch and move,
really easy, 10 lines of code.
And we do have sample code to
prove that, so you can check.
How can you use that?
You just create an
instance of your own class
in this delegate method.
And on finish or cancel what
happens is while you are
changing this transition
progress property,
we are actually tracking
the current velocity.
So we will match that
when we finish or cancel
and drive the end
of this animation.
And because you might sub-class,
you might have your own
parameters, it would be nice
to be able to actually
participate
in that nice velocity matching.
So you can actually ask
us to track your values,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and then in this final phase
you can access an updated value
in sync with our own animation.
So I'd like to show you
what you can do with that.
A very simple custom
layout, a stack layout that's
in a collection view
controller implemented
in navigation controller.
So I have this nice layout
to layout automatic mode.
We add it to collection view
controller, so when I tap I go
to the next collection
view controller.
I can tap back, and I'm back --
I'm back to the first
collection view controller.
Plus I can also drive
interaction
by implementing the interactive
view controller transitioning
protocol with a gesture, and
I can do something like that.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So the current layout right
now is a transition layout,
I can cancel, and I'm back to
the first layout automatically.
And I can pinch to completion.
And that is the small
effect of the end.
And what's great is I can pinch
back, which is actually a pop
to the previous view controller.
And pay attention to
the navigation bar.
[ Silence ]
And that's just one
line of code.
Because the only thing I'm doing
is I'm using the view controller
API to track this
percent progress.
We have a few other
enhancements in collection view
for transitions,
targetContentOffset
FoProposedContentOffset.
When you're updating data
sources, changing layouts,
or changing bounds
for a collection view,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
we try to guess what is the
best content offset for that.
Sometimes it's just our
best guess, but not correct.
If you actually want to specify
exactly what this ending content
offset should be, you
can implement this method
in your layout, and we're going
to use the exact
content offset you return
for this bounds change,
data source update,
or collection view
layout transition.
We have three new method on
UI collection view layout,
so you can be notified
when we are about to move
to the next layout, and
from another layout.
We have better animations
in layout transition
by supporting the initial and
final layout attributes method,
and we have a new
completion handler
for the automatic set
collection view layout animated.
And that's it for
collection view.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
I'd like to bring
back Bruce, thank you.
>> Thanks, Olivier.
So we're going to talk more
about some of the details
of interactive transitions now.
In particular, we're going
to talk a little bit
about cancellation.
So that's that state
diagram that I had showed
in an earlier slide, and we're
going to kind of zoom in on kind
of the two different states,
or paths that you can go
through as an interactive
transition comes to an end.
And so as an interactive
transition starts,
the machinery behind in
UIKit is actually going
to be making calls out
to view will appear,
view will disappear, will show
view controller, all the stuff
that you've normally used to
kind of control what's happening
in your application as things
come on and off screen.
And typically what happens
is we go from disappeared
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to appearing, to
appeared to disappearing.
That's when life is good.
However, we can also do this.
We can go from appearing
to disappearing,
and from disappearing
back to appearing.
Now the reality is we
could do this even in iOS 5
if you built a custom
-- well not a custom,
but you built your own
container view controller.
These are kind of
legal transitions,
but now they're appearing a
lot more when you can kind
of cancel based on an
interactive gesture.
Take home message
here is don't assume
that view did appear
follows view will appear,
or view will disappear, or view
did disappear will follow view
will disappear.
Some colleagues of mine have
rid me kind of ruthlessly
that view will appear really
should probably be called view
might appear, or view
will probably appear,
or I really wish this
view would appear.
But most of the time
what it's saying is true.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
But now you've got
to kind of take
into account that
maybe it won't.
And so we've added some new API
to help you deal
with some of this.
And to do that, we've introduced
a new object that you can get
when you're in a transition.
And you get it by asking
the view controller --
one of the view controller
participants of the transition.
It can really be the
presenting, the presented,
the push, the pop, whatever.
As long as they're
involved in a transition,
you can get this thing called
a transition coordinator.
And the first thing
I'd like to point
out is the transition
coordinator conforms
to this other thing called a
transition coordinator context.
It's really that one of
these protocols is passive,
and the coordinator kind of
sub-protocol as it were kind
of adds an active part to it.
And in particular this
one that I've highlighted,
notify when interaction ends
using block is what you can use
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to help manage the untoward
effects of view did disappear
and not actually being called
when you expected it to.
So one of the things about the
coordinator context, you know,
the passive component, is
that it has these
interesting properties,
like was the transition
cancelled, or did it start
out as an interactive
transition,
is it still interactive?
And you can ask all
those questions
as the transition is unfolding,
and in particular you can ask
that question inside of a
block that you have posted,
that you've asked the transition
coordinator to execute
at a certain point in the
interactive transition.
So say you have view
will appear,
and in your view will
appear you have some method
that does all these
kind of side effects,
assuming that view did appear
is going to get called.
And believe me, there's
lots of you out there
that have methods like that.
I know we do.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And what you're going to
do is you're going to call
that method, and then within the
same lexical scope you're going
to ask for a transition
coordinator, and you're going
to check wait, am I in --
is this even interactive
to begin with?
And if it is interactive,
you're going to call notify
when interaction ends.
That doesn't mean that
the transition ends.
There's -- again, there's this
important differentiation.
There's the interactive
portion of a transition,
then there's the portion
where it kind of finishes,
and then you -- then
it's over for real.
So this block that you're going
to call is going to get called
when the interactive
portion ends.
And at that point you can
ask the context that's passed
in hey, did I get
cancelled or not?
And if you did get cancelled,
you can then undo the side
effects that you were expecting
to get undone in
view did appear.
Okay. So that's kind of nice.
Least there's a way
to manage that.
But the transition
coordinator's kind of cool,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
because as we implemented it,
we realized that it was
actually really easy
to do a few other things that a
lot of you have been requesting.
So one is that you can basically
get a completion handler to run
when the entire transition
really completes.
I don't mean when the
interactive portion ends,
I mean when the whole
thing is done, you know,
like the completion
handler that's
on present view controller,
or dismiss view controller.
Another thing that you can do
is you can say you know what?
When this transition
runs, and is animating,
I want to run this other thing
within the animation
block of the transition.
Now I don't know how many
of you out there have kind
of been saying okay, how long
does this push view controller
transition take?
And you get out your stopwatch,
and you figure it out,
because you want to do
something that's kind
of synchronized with
that animation.
Well you don't have to do that
anymore, because there's now API
on transition coordinator
that you can animate alongside
the running transition.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So to make that more
useful -- I mean this works,
the transition coordinator
works for any custom transition
that you might build yourself,
but it also works for our
out of the box UI navigation
controller transitions,
just regular push pop
set view controller.
So in other words, you can get
a transition coordinator for an
out of the box navigation
controller transition.
It will also work for
present and dismiss.
So it's kind of useful now,
because you can do
stuff like this.
First of all let's
look at the methods.
There's two of them, one is
called -- one is the easier one,
it's called -- there's
a typo there,
it's animate alongside
transition completion,
and the other is animate
alongside transition
in view animation completion.
And basically you pass
in an animation block
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
that animates alongside, you
pass in a completion handler
that runs after it's all done,
and the second variation is kind
of a more advanced feature.
Most of the time you don't need
it, because if you're trying
to animate something
alongside the transition,
which is within the view
hierarchy of the container view
that you know about, because
it's in the context objects
that you can query
about, then you don't need
to specify the other view.
But sometimes you might have
a view that you actually want
to do an animation in
that is actually not part
of the view hierarchy that the
transition is taking place in.
And in that case you
can specify that view,
and that's what the second
API variant is all about.
So, let's have some fun with it.
Push view controller
animated yes.
And what you want
to do is you want
to have a completion
handler that runs
after the push finishes.
What you're going to
do is you're going
to grab a transition
coordinator,
and then you're just going
to call animate alongside
transition.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
You don't even have
to pass in anything
for the animation
portion, just pass in nil.
Specify completion block,
and now you have a
completion handler
on push view controller
-- pop view controller.
An interesting point of
difference is is that --
and hopefully none of you rely
on this, but I'm going to kind
of spell it out because I
have a little bit of time --
is that push view
controller animated yes used
to be a little more
eager prior to iOS 7.
In iOS 7 now, push view
controller animated yes is going
to kind of defer its
transition the same way
that push view controller
animated no did.
So for most of you that's
not going to be an issue,
but keep in mind that we kind of
-- it's an implementation detail
about the exact timing of
when the actual transition's
animations commence or not.
Alright. So, I like this quote.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
We've kind of created a lot
of things here, and
you can go crazy.
And I want to give
you an example
of what might be irresponsible.
So here I have a view controller
and navigation controller,
and I'm using UI kit dynamics,
and [Laughter] so it's kind
of fun, but maybe you don't
want to build your UI like that.
So let's do a quick
summary, and then I'm going
to talk a little bit
about what we're going
to talk about this afternoon.
We have basically provided
you guys with a lot
of new UIView based
animation APIs.
We created a brand new
snapshotting mechanism
that you can use with them,
and you can go wild
creating fantastic animations
and view controller transitions.
All these view controller
transitions can be customized,
UICollectionView
controller can be used now,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
it can be used really
well with the inside
of a navigation controller.
It's protocol-based,
which might seem
like it's a little abstract,
but it actually gives
you an incredible amount
of flexibility, because
we're not binding you
to any specific object
to implement
that animation controller, or
the interaction controllers.
Remember that you can create
interactive transitions
and view will appear and view
will probably appear might be
more appropriate, and you need
to possibly take
action for that.
We've created a brand new object
called a transition coordinator
that provides some
great new functionality,
as well as a means to
deal with the cancel phase
of an interactive transition.
And for more information
on this,
please contact our fearless
evangelist, Jake Behrens.
I would like to point out a
couple of related sessions,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and one of which is going
to be this afternoon
that Ol [phonetic] and I --
Ol by the way, in addition to
collection views, you know,
has changed the gravitational
constant in UIKit.
And we're going to be talking
about how to use UI kit dynamics
in a more advanced way, and in
particular I will be talking
about using it with transitions.
And that's it.
Thank you for coming, have
a great rest of the day.
[ Applause ]
[ Silence ]